Powershell:从另一个 BAT 运行一个 BAT 并提供变量

Powershell: Run a BAT from another BAT and Supply Variables

提问人:tnpir4002 提问时间:1/5/2023 最后编辑:mklement0tnpir4002 更新时间:1/6/2023 访问量:98

问:

超短版本:我有一个巨大的 BAT 文件,我希望将其制作成一个较小的子 BAT 文件系列,我可以在提供变量的同时从单个父 BAT 文件运行。

困惑?

示例:我现在拥有的主要 BAT 文件所做的一件事是它扫描了多个不同的位置以查找碎片文件和文件夹,并将它们删除。每次扫描都是相同的措辞,唯一改变的是文件夹。

所以我想做的是构造一个 BAT 文件,它执行如下操作:

Run Clear_Debris.bat
$searchdrive = "H:\"

Run Clear_Debris.bat
$searchdrive = "W:\"

Run Drive_Migration.bat
$sourcedrive = "H:\"
$destdrive = "W:\"

等等。基本上,单个 BAT 可以调用其他 BAT(没有为变量指定值),并指定这些 BAT 应使用哪些值作为其变量的值。这样,我就可以将所有单独的函数分解成它们自己的 BAT 文件,在需要时可以单独运行这些文件,或者当我需要对其中一个例程进行更改时,我只需要在一个地方而不是多个地方进行更改。

这可能吗?

变量 批处理文件 cmd 脚本

评论

1赞 postanote 1/5/2023
这似乎真的很令人费解。为什么是这个用例,而不是仅仅在 PS 中原生执行此操作?老实说,要么使用 .bat/.cmd 要么使用 .ps1。指定变量的方式仅在 PS 中起作用。您可以本机使用 .bat/.cmd 并直接使用那里的变量方法。请参阅以下资源: “批处理文件变量” 如果在企业环境中执行此操作,则只需使用 Windows Server FSRM 进行文件/文件夹管理即可。蝙蝠里有什么?
0赞 tnpir4002 1/5/2023
我只是给出了 BAT 文件实际具有的一小部分示例。这是一个完整的简化: * 将文件从一个驱动器复制到另一个驱动器(4 次) * 清除文件夹中的碎片(4 次) * 在目录中搜索具有特定名称的文件夹并移动到深层存储(4 次) * 将目标文件夹镜像回源(4 次) 因此,在单个 BAT 文件中发生了很多事情,重复了很多步骤, 我想通过使用不同的变量重复运行相同的批次来使事情变得更简单。
0赞 mklement0 1/5/2023
请注意,PowerShell 是任务附带的,因为你要创建批处理文件。(示例代码使用 PowerShell 语法创建变量,这在批处理文件中不起作用)。

答:

2赞 mklement0 1/5/2023 #1
  • 将所有 () 文件放在同一个文件夹中。.bat.cmd

  • 使用命令调用每个从属批处理文件,以确保在主批处理文件中继续执行。call

  • 使用路径前缀来确保从属批处理文件可以位于主批处理文件旁边,而不管工作目录是什么( 扩展到执行批处理文件所在目录的完整路径,始终后跟 - run 以获取详细信息)%~dp0%~dp0\for /?

    • 相反,如果要将从属批处理文件放在主批处理文件的子文件夹中,请说 ,只需附加该文件夹的名称,例如 。util%~dp0util\
  • 从属批处理文件会自动查看主批处理文件的变量,但您可以使用以下命令本地化在从属批处理文件中执行的变量更改setlocal

    • 但是,为了概念清晰和可维护性,请考虑将下属批处理文件设计为接受主批处理文件在调用时传递的参数,在被调用方中可访问为 、 、 ...%1%2

主批处理文件的概要:

@echo off & setlocal

:: Run Clear_Debris.bat
set "searchdrive=H:\"
call "%dp0Clear_Debris.bat"

:: Run Clear_Debris.bat with a different %searchdrive% value.
set "searchdrive=W:\"
call "%~dp0Clear_Debris.bat"

:: ...

您可能还希望对每个值之后的值执行操作,以检查从属批处理文件是否报告了错误。%ERRORLEVEL%call

评论

0赞 tnpir4002 1/6/2023
讨厌说出来,但它没有按预期工作。主 BAT 文件确实出现了,但它没有将我设置的值转发到第二个 BAT 文件。
0赞 tnpir4002 1/6/2023
这是我的语法:“@echo off & setlocal set ”$sourceDir=K:\Work Stuff VI“ call ”Subroutines\Clear_Debris.bat”
0赞 tnpir4002 1/6/2023
问题是,当Clear_Debris.bat运行时,变量 $sourceDir 没有值(如果这有什么不同,它被格式化为 Powershell 命令)。
0赞 tnpir4002 1/6/2023
可能还值得注意的是,Clear_Debris.bat文件调用 Powershell 工具来完成其工作;这就是为什么我说它是为 PowerShell 设置格式的。这是命令之一:“Get-ChildItem -recurse -path $sourceDir -filter $searchfolder |remove-item -force -recurse -verbose“ 所以我要做的是在 super-BAT 文件中定义$sourceDir,然后让它以该值Clear_Debris.bat运行$sourceDir。
0赞 tnpir4002 1/6/2023
想通了:必须将“$sourceDir=$Env:sourceDir”添加到Clear_Debris.bat