当我从 bat 文件运行以下代码时,收到一条错误消息,指出访问被拒绝,因为我没有以管理员身份运行。
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File ".\test.ps1"
当我以管理员身份运行 .bat 文件时,出现错误,提示找不到 powershell 文件。
当我不以管理员身份运行bat文件时,错误消息的第二行显示它能够找到文件路径,所以我很困惑为什么它无法以管理员身份找到路径。
最佳答案
您所指的 PowerShell 脚本文件 test.ps1
位于当前目录 (.\
)
除非您事先明确设置当前目录或使用绝对路径(见下文),否则您的批处理文件将无法正常工作。
恰当的例子:
通过双击从文件资源管理器打开批处理文件会使批处理文件所在的目录成为当前目录,因此如果您的
.ps1
脚本位于相同目录中,该调用将在这种情况中工作。相比之下,当您打开带有海拔的批处理文件时,右键单击并选择
以管理员身份运行
,C:\Windows\System32
将是当前目录,并且您的调用将失败。
解决方案:
要么:显式将批处理文件自己的目录设置为当前目录:
pushd "%~dp0" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File ".\test.ps1" popd
注意:
使用
pushd
是最可靠的解决方案,因为如果通过调用批处理文件,
cd/d "%~dp0"
将不起作用em>UNC 路径。与cd
不同,pushd
自动将驱动器号映射到给定的 UNC 路径,这是必要的,因为cmd.exe
不允许直接使用UNC路径作为工作目录;pushd
从Z:
开始向后查找未使用的驱动器号。但是,为了再次释放该驱动器号,需要配对
popd
调用,而如果您组合cd/d "%~ dp0"
与setlocal
(见下文),无需采取进一步操作。如果您不需要支持通过 UNC 路径调用,您也可以使用 cd/d "%~dp0"|| exit/b,如果进行此类尝试,它会简单地以退出代码
1
中止执行。
无论哪种情况,建议将
setlocal
放在批处理文件的开头,以便工作目录中的更改仅限于批处理文件 并且不影响调用者;例如,使用@echo off & setlocal
启动批处理文件。
请注意,setlocal
还会使在批处理文件中创建或修改的任何变量成为该脚本的本地变量,但这通常也是可取的。
或者,如果当前目录并不重要,只要您定位正确的
.ps1
文件即可:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "%~dp0test.ps1"
至于%~dp0
的语法:
%~dp0
扩展为批处理文件自身目录的完整路径;语法在 call/?
的输出中进行了解释,但是,简而言之:%0
指的是调用的批处理文件名或路径 ,并且 ~dp
修改它以报告(仅)驱动器 (d
) 和完整目录路径 (p
)。
关于powershell - 仅当以管理员身份运行时无法从 .bat 文件找到 powershell 文件的文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73979021/