我有一个奇怪的案例,我无法理解...的原因。
请知道我是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}
正如Mathias在对该问题的评论中所指出的那样,该语句不会调用您的函数,而是将其包装在script block(
{ ... }
)[1]中,该片段是可重复使用的代码(就像函数指针,松散地说),供以后通过&
,call (execute) operator执行。要调用您的函数,只需使用它的名称(在此没有参数要传递的情况下,请单独使用):
installMS32Bit
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'
I like to see progress and like to have secondary windows open to monitor the new process being run. I was unable to find a solution with a persistent window that worked for me to do this without 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]由于您没有将正在创建的脚本块分配给变量,因此它是隐式输出的(在没有重定向的情况下打印到显示中);脚本块按其文字内容进行字符串化处理,但不包括封闭的
{
和}
,因此字符串installMS32Bit
将显示在显示屏上。
关于powershell - PowerShell函数未按预期运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60284437/