powershell 中的 %~dp0 等效项(使用 Expand-Archive cmdlet)

SrP*_*aux 5 windows powershell cmd batch-file

我对脚本编写(尤其是 powershell)和 Stack Overflow 都很陌生,所以请原谅我的无知并请耐心等待!我将尽力具体解释我想要做什么,并希望有人能够详细答复我可以做些什么来使其发挥作用。

预期流程/工作流程:同事下载包含所有必需文件的“Install.zip”文件。此“Install.zip”文件包含“Setup.bat”文件(用于计算机配置)、“Fubar.zip”文件、2 个 powershell 脚本和一个自定义 powerplan (.pow) 文件。下载后,他们将运行“Setup.bat”文件,它几乎可以完成所有工作。在该批处理文件中,它调用 2 个 powershell 脚本。1)"Download.ps1" - 从网络下载一些其他文件。2.) “Unzip.ps1” - 解压“Fubar.zip”并将内容放入另一个文件夹 - C:\TEST\

问题:我最近熟悉了在批处理文件中使用 %~dp0 。我想确保我的同事最初下载 Install.zip 的位置不会丢失我的批处理文件。例如,有些人会将 .zip 文件下载到“下载”文件夹,然后将内容解压到正确的目的地。其他人会将 .zip 下载到特定文件夹,然后将其解压到该文件夹​​中。[例如:C:\Alex\Install.zip --Extraction-- C:\Alex\Install\((Content))] 因此,由于变量的原因,我尝试不预先定义文件位置。我已经让 %~dp0 在我的批处理文件中需要它的任何地方工作。我遇到的唯一问题是让我的 powershell 脚本使用我的批处理文件所在的同一工作目录。 *我的批处理文件和我的 powershell 脚本将始终位于同一目录中。(无论在哪里)

目标:我希望我的 powershell 脚本(“Unzip.ps1”)在当前运行的同一目录中查找“Fubar.zip”文件。(再次 - 无论在哪里)我基本上想删除任何变量可能会抛出 powershell 脚本。我希望它始终使用当前工作目录来查找 Fubar.zip。我基本上需要 powershell 来使用其当前工作目录或找出一种方法让它拉出当前工作目录并使用它来查找“Fubar.zip”。

我当前的“Unzip.ps1”powershell 脚本非常基本。

解压.ps1 :Expand-Archive -Force c:\ALEX\Install.zip\Fubar.zip -dest c:\TEST\

调用 Unzip.ps1 脚本的批处理文件命令: Powershell.exe -executionpolicy remotesigned -File %~dp0UNZIP.ps1

请记住,我只是在学习脚本并且正在自学。我的知识有限,但到目前为止我已经做到了,这是我唯一坚持的部分。请给予明确答复。任何帮助或建议将不胜感激!使用PowerShell 5.0

提前致谢!

mkl*_*nt0 7

PowerShell v3+ 中 的cmd.exe等效项是:%dp0$PSScriptRoot

两种构造都扩展为包含手头批处理文件/PowerShell 脚本的文件夹的绝对路径。
(唯一的区别是%dp0包含一个尾随\,与 不同$PSScriptRoot)。

因此,要使Unzip.ps1脚本引用Fubar.zip位于脚本本身所在的同一文件夹中,请使用:

Expand-Archive -Force $PSScriptRoot\Fubar.zip -dest c:\TEST\
Run Code Online (Sandbox Code Playgroud)
  • 将路径构造为$PSScriptRoot\Fubar.zip- 即,盲目地将变量值和文件名与\- 相连接,是更正确表达为 的实用快捷方式(Join-Path $PSScriptRoot Fubar.zip)在这种情况下使用是安全的,但请参阅评论以了解有关何时Join-Path使用的讨论。

  • 自动$PSScriptRoot变量需要PS v3+;在 v2- 中,使用
    Expand-Archive -Force ((Split-Path $MyInvocation.Mycommand.Path) + '\Fubar.zip') -dest c:\TEST\


Ver*_*Ray 4

根据您的描述,我收集到的信息Fubar.zip位于Unzip.ps1同一目录中。我们假设这个目录是C:\Users\Me\Temp;尽管我知道这可能会有所不同。

Powershell 的工作目录将是您启动时所在的目录(如果从 CMD 调用);否则,它将来自$env:UserProfile. 由于.bat文件总是Unzip.ps1从它所在的目录 ( C:\Users\Me\Temp) 调用,powershell.exe 将使用此命令找到它(您仍然可以%~dp0在此处使用;它不会造成任何损害):

powershell.exe -ExecutionPolicy RemoteSigned -File Unzip.ps1
Run Code Online (Sandbox Code Playgroud)

在 的内部Unzip.ps1,您将使用Get-Location

Expand-Archive -Force "$(Get-Location)\Fubar.zip" -dest c:\TEST\
Run Code Online (Sandbox Code Playgroud)

但是,如果该.bat文件进入cd另一个目录,则这将不起作用。从你的%~dp0UNZIP.ps1例子来看,我认为情况并非如此,但无论如何我们还是要解决这个问题。如果是这种情况,则需要从脚本所在的位置进行处理。因此,对于此调用,完整/关系路径为.ps1

powershell.exe -ExecutionPolicy RemoteSigned -File C:\Users\Me\Temp\Unzip.ps1
Run Code Online (Sandbox Code Playgroud)

然后,您的遗嘱Unzip.ps1需要如下所示:

Expand-Archive -Force "${PSScriptRoot}\Fubar.zip" -dest 'C:\TEST\'
Run Code Online (Sandbox Code Playgroud)

或者,您也可以按照 @JosefZ 的建议进行一些奇特的路径分割。和变量包含脚本的完整路径$PSCommandPath$MyInvocation您应该熟悉以下内容:

$location = Split-Path $PSCommandPath -Parent
$location = Split-Path $MyInvocation.MyCommand.Path -Parent
Expand-Archive -Force "${location}\Fubar.zip" -dest 'C:\TEST\'
Run Code Online (Sandbox Code Playgroud)

注意: 当然,你不会设置$location两次。我只是向您展示两种设置方法。

我希望这有帮助!