首页/系统/Windows 运维速查/脚本自身路径 $PSScriptRoot
PowerShell 基础66 条

脚本自身路径 $PSScriptRoot

获取当前脚本所在目录,用于构造与脚本相对的路径,避免依赖“当前工作目录”导致找不到配置文件。

Windows 运维速查系统更新于 2026-10-13

$PSScriptRoot 是什么

$PSScriptRoot 是 PowerShell 的自动变量,值是「当前脚本文件所在目录」,用来把配置、日志、数据文件定位到脚本旁边,而不是依赖调用者当时的工作目录。它解决的是脚本最容易出问题的一类场景:双击运行、被计划任务拉起、被别的脚本调用时,当前目录各不相同,写相对路径就会「在我机器上能跑,在服务器上找不到文件」。

基本信息

适用平台PowerShell 3.0 及以后(Windows 8/Server 2012 起自带)
取值脚本文件所在目录的绝对路径,不带文件名
配套变量$PSCommandPath 含文件名的完整路径、$MyInvocation.MyCommand.Path 等价写法
可用范围只在脚本文件(.ps1)、模块脚本、点源脚本内有效
不可用范围交互式控制台、-Command 一行式命令中为空
典型用法Join-Path $PSScriptRoot 'config.ini' 组合同目录文件的绝对路径

典型使用场景

  • 读取同目录配置:脚本与 config.ini 一起发布,走到哪都读同一份
  • 写日志到脚本目录:便于直接查看与打包,不依赖启动目录
  • 定位同目录子模块:加载 .\lib\Helpers.ps1 这类随脚本分发的文件
  • 计划任务运行:任务的工作目录默认是系统目录,路径必须从脚本自身派生
  • 注册表式落地:脚本内统一切换到自身目录,避免后续相对路径写错位置

常用示例

常用示例
$cfg = Join-Path $PSScriptRoot 'config.ini'          # 同目录下的配置文件
Get-Content -Path $cfg -Encoding UTF8
$log = Join-Path $PSScriptRoot 'run.log'              # 同目录写日志
"$(Get-Date -Format s) start" | Add-Content -Path $log -Encoding UTF8
$lib = Join-Path $PSScriptRoot 'lib\Helpers.ps1'
. $lib                                                # 点源加载同目录的辅助脚本
Split-Path -Parent $PSCommandPath                     # 等价写法:从完整路径取目录
Set-Location -LiteralPath $PSScriptRoot               # 明确切换工作目录(谨慎使用)

相关路径变量对照

变量/表达式含义什么时候不对
$PSScriptRoot脚本文件所在目录交互式会话与 -Command 中为空
$PSCommandPath脚本文件完整路径同上;管道线上下文中可能为空
$PWD当前工作目录(PowerShell 位置)随 Set-Location 与调用方式变化
[Environment]::CurrentDirectory.NET 视角的当前目录与 PowerShell 当前位置可能不一致
$HOME / $env:USERPROFILE当前用户配置目录服务账户下指向系统配置目录,易误写
在交互式命令行或 -Command 传参的一行式命令里 $PSScriptRoot 是空值,直接拼接会得到相对路径或报错;这类场景用 $PWD 或显式传入路径。
PowerShell 的当前位置($PWD)与 .NET 的当前目录([Environment]::CurrentDirectory)是两个东西,某些 .NET 方法读写文件时按后者解析相对路径,出现「PowerShell 里能找到、代码里找不到」时优先怀疑这里。

计划任务里的稳妥写法

计划任务里的稳妥写法
# 计划任务把脚本放在 D:\ops\cleanup.ps1,工作目录默认是 C:\Windows\System32
$root = $PSScriptRoot
$data = Join-Path $root 'data'                       # 一律用绝对路径
if (-not (Test-Path $data)) { New-Item -ItemType Directory -Path $data | Out-Null }
Start-Transcript -Path (Join-Path $root 'run.log') -Append   # 留痕便于排错
用 Set-Location $PSScriptRoot 把工作目录改成脚本目录会连带影响脚本内其它相对路径与外部程序调用的上下文,属于全局状态改动;更稳的做法是保持工作目录不变,所有路径都用 Join-Path 拼绝对路径。

易错点

  • 在交互式会话或一行式命令里使用 $PSScriptRoot,得到空值并拼出错误路径,脚本报文件不存在
  • 脚本依赖相对路径(如 .\config.ini)读取配置,被计划任务或其它目录调用时找不到文件
  • 把 $PSScriptRoot 与 [Environment]::CurrentDirectory 混为一谈,.NET 方法按系统目录解析路径导致写错位置
  • 脚本里随手动 Set-Location 改变工作目录,后续相对路径全部偏移,行为难以复现
  • 在 PowerShell 2.0 环境下使用 $PSScriptRoot:该变量自 3.0 才提供,需改用 $MyInvocation.MyCommand.Path

数据来源与参考

  • Microsoft Learn:about_Automatic_Variables

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌