如何使用正确的工作目录从 BAT 文件启动 PowerShell 脚本?

Hoo*_*och 6 windows powershell cmd batch-file

我正在尝试创建 bat 脚本,该脚本可以在正确的工作目录中启动与 bat 文件名称相同的 PowerShell 脚本。

这是我得到的:

@ECHO OFF
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -WorkingDirectory '%~dp0' -Verb RunAs}"
PAUSE
Run Code Online (Sandbox Code Playgroud)

以这种方式传递工作目录不起作用。

如何制作将传递正确工作目录和命令行参数的脚本?

Ven*_*ryx 10

使用时该-WorkingDirectory参数不起作用-Verb RunAs。相反,您必须通过在字符串cd中调用来设置工作目录-Command

这就是我使用的:(cmd/batch-file 命令)

powershell -command "   Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%cd%'; & 'PathToPS1File';`\""\""   "
Run Code Online (Sandbox Code Playgroud)

如果您想在 Windows 资源管理器中创建“以管理员身份运行脚本”右键单击命令,请在 处创建一个新的注册表项HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Run with PowerShell (Admin)\Command,并将其值设置为上面的命令 - 除非替换%cd%%W,PathToPS1File%1(如果您希望它执行右键单击的文件)。

结果:(Windows 资源管理器上下文菜单 shell 命令)

powershell -command "   Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%W'; & '%1';`\""\""   "
Run Code Online (Sandbox Code Playgroud)

编辑:还有另一种方法可以让脚本从资源管理器以管理员身份运行,即使用“runas”子键: https: //winaero.com/blog/run-as-administrator-context-menu-for-power -shell-ps1-文件


如果您想从现有的 powershell 以管理员身份运行脚本,请删除外部 powershell 调用,替换为%W$pwd替换%1为 ps1 文件路径,然后将每个替换\"""

注意:\""'s 只是转义引号,用于从 Windows shell/命令行调用时(它的引号处理很糟糕)。在这种特殊情况下, just\"也应该可以工作,但我使用更健壮的函数\""来更容易扩展。

请参阅此处了解更多信息:/sf/answers/2198961131/

结果:(PowerShell 命令)

Start-Process PowerShell -Verb RunAs "-Command `"cd '$pwd'; & 'PathToPS1File';`""
Run Code Online (Sandbox Code Playgroud)

重要提示:上述命令假设您的计算机已配置为允许脚本执行。如果不是这种情况,您可能需要添加-ExecutionPolicy Bypass到您的 powershell 标志。(您可能还想-NoProfile避免运行配置文件脚本

  • 好的; 但是,使用“'”来引用文件系统路径是有问题的,因为“'”是合法的文件名字符 - 最好使用“”。在最后一个命令的情况下,这意味着:“Start-Process PowerShell -Verb RunAs” "-命令 cd \\`"$pwd\\`"; & \\`"PathToPS1File\\`""` (3认同)

小智 5

解决方法是让 PowerShell 脚本将目录更改为它自己的源:

Set-Location (Split-Path $MyInvocation.MyCommand.Path) 
Run Code Online (Sandbox Code Playgroud)

作为第一个命令。

根据mklement0的提示:在 PSv3+ 中使用更简单的:

Set-Location -LiteralPath $PSScriptRoot
Run Code Online (Sandbox Code Playgroud)

或者使用该目录打开相邻的文件。

$MyDir = Split-Path $MyInvocation.MyCommand.Path
$Content = Get-Content (Join-Path $MyDir OtherFile.txt)
Run Code Online (Sandbox Code Playgroud)