【问题标题】:PowerShell function not running as expectedPowerShell 函数未按预期运行
【发布时间】:2020-06-02 16:23:57
【问题描述】:

我有一个奇怪的案例,我无法理解原因......

请知道我是 PowerShell 的新手。

我正在开发一个 PowerShell 菜单系统,以帮助在我的环境中自动构建新计算机。我有一个包含应用程序安装脚本的 PS1 文件。当我使用脚本来引用它时,我可以运行它并且没有问题。但是,当我尝试将其插入函数并引用它时不会。

这行得通:

4       #   Microsoft Office 32-bit
            {
                Write-Host "`nMicrosoft Office 32-bit..." -ForegroundColor Yellow

                # {installMS32Bit}
                Invoke-Expression "cmd /c start powershell -NoExit -File '\\**SERVERPATH**\menuItems\ms_office\32-bit\install.ps1'"

                Start-Sleep -seconds 2
            }

这不是:

function installMS32Bit(){

Invoke-Expression "cmd /c start powershell -NoExit -File '\\**SERVERPATH**\menuItems\ms_office\32-bit\install.ps1'"
}

}

4       #   Microsoft Office 32-bit
            {
                Write-Host "`nMicrosoft Office 32-bit..." -ForegroundColor Yellow

                {installMS32Bit}

                Start-Sleep -seconds 2}

install.ps1 文件:

    # Copy MS Office uninstall and setup to local then run and install 32-bit Office
Copy-Item -Path '\\**SERVERPATH**\menuItems\ms_office\setup.exe' -Destination 'C:\temp\' -Force
Copy-Item -Path '\\**SERVERPATH**\menuItems\ms_office\uninstall.xml' -Destination 'C:\temp\' -Force
Copy-Item -Path '\\**SERVERPATH**\menuItems\ms_office\32-bit\Setup.exe' -Destination 'C:\temp' -Force

Invoke-Expression ("cmd /c 'C:\temp\setup.exe' /configure 'C:\temp\uninstall.xml'")

Start-Process -FilePath 'C:\temp\Setup.exe'

关于 Invoke-Expression 的第二个问题和一点解释...

我喜欢查看进度并喜欢打开辅助窗口来监控正在运行的新进程。在没有 Invoke-Expression 的情况下,我无法找到具有持久窗口的解决方案。

如果有更好的方法在 PowerShell 中执行此操作,我会全力以赴!

【问题讨论】:

  • {installMS32Bit} -> installMS32Bit (否则你只是定义了一个新的脚本块而不执行它)

标签: powershell cmd batch-processing


【解决方案1】:

{installMS32Bit}

正如Mathias 在对该问题的评论中指出的那样,此语句不会调用您的函数,它将其包装在script block (@987654329 @)[1],这是一段可重用的代码(就像函数指针,松散地说),供稍后通过&,call (execute) operator 执行。

要调用你的函数,只需使用它的名字(在这里单独使用它,因为没有参数可以传递):@987654331 @

Invoke-Expression should generally be avoided;绝对是don't use it to invoke an external program,就像你的尝试一样。

此外,一般不需要通过cmd.exe (cmd /c ...)调用外部程序,只需直接调用即可。

例如,将您问题中的最后一个 Invoke-Epression 电话替换为:

# If the EXE path weren't quoted, you wouldn't need the &
& 'C:\temp\setup.exe' /configure 'C:\temp\uninstall.xml'

我喜欢查看进度并喜欢打开辅助窗口来监控正在运行的新进程。在没有 Invoke-Expression 的情况下,我无法找到具有持久窗口的解决方案。

(在 Windows 上),Start-Process默认在新窗口中异步执行控制台应用程序(除非您指定 -NoNewWindow)(除非您指定 -Wait)。

您不能将.ps1 脚本直接传递给Start-Process(它将被视为文档打开而不是可执行文件 调用),但您可以通过-File 参数将其传递给PowerShell's CLI:

Start-Process powershell.exe '-File install.ps1'

以上简称:

Start-Process -FilePath powershell.exe -ArgumentList '-File install.ps1'

也就是说,PowerShell 将在新窗口中执行以下操作:
powershell.exe -File install.ps1


[1] 由于您没有将正在创建的脚本块分配给变量,因此它是隐式 output (在没有重定向的情况下打印到显示器);脚本块通过其文字内容进行字符串化,不包括封闭的{ 和},因此字符串installMS32Bit 将打印到显示器。

【讨论】:

  • 这正是我需要的答案。 Mathias 的建议和您的定义解决了这个难题。我无法告诉你我看了多长时间以及 Start-Process 的所有不同示例。没有一个站点明确说明将 -File 放入带有 ps1 文件路径的参数列表中。这完全解决了我的问题!
猜你喜欢
  • 2011-10-31
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多