PowerShell 函数未按预期 运行
PowerShell function not running as expected
我有一个奇怪的案例,我无法理解...
请注意我是 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-bit\install.ps1'"
Start-Sleep -seconds 2
}
这不是:
function installMS32Bit(){
Invoke-Expression "cmd /c start powershell -NoExit -File '\**SERVERPATH**\menuItems\ms_office-bit\install.ps1'"
}
}
4 # Microsoft Office 32-bit
{
Write-Host "`nMicrosoft Office 32-bit..." -ForegroundColor Yellow
{installMS32Bit}
Start-Sleep -seconds 2}
安装。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-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 的一点解释...
我喜欢看到进展,并且喜欢打开辅助 windows 以监视正在 运行 的新进程。我无法找到具有持久性 window 的解决方案,该解决方案在没有 Invoke-Expression 的情况下对我有用。
如果有更好的方法在 PowerShell 中执行此操作,我会洗耳恭听!
{installMS32Bit}
如Mathias points out in a comment on the question, this statement doesn't call your function, it wraps it in a script block ({ ... }
)[1], which is a piece of reusable code (like a function pointer, loosely speaking), for later execution via &
, the call (execute) operator.
要调用你的函数,只需使用它的名字(在这里单独使用,假设没有参数通过):installMS32Bit
Invoke-Expression
should generally be avoided; definitely ,正如您的尝试。
此外,一般不需要通过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
默认情况下 在新的 window 中执行控制台应用程序(除非您指定 -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 将在一个新的 window 中执行以下 :
powershell.exe -File install.ps1
[1] 由于您没有将正在创建的脚本块分配给变量,因此它隐含地 output (打印到显示器,在没有重定向);脚本块按其文字内容进行字符串化,不包括封闭的 {
和 }
,因此字符串 installMS32Bit
将打印到显示器。
我有一个奇怪的案例,我无法理解...
请注意我是 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-bit\install.ps1'"
Start-Sleep -seconds 2
}
这不是:
function installMS32Bit(){
Invoke-Expression "cmd /c start powershell -NoExit -File '\**SERVERPATH**\menuItems\ms_office-bit\install.ps1'"
}
}
4 # Microsoft Office 32-bit
{
Write-Host "`nMicrosoft Office 32-bit..." -ForegroundColor Yellow
{installMS32Bit}
Start-Sleep -seconds 2}
安装。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-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 的一点解释...
我喜欢看到进展,并且喜欢打开辅助 windows 以监视正在 运行 的新进程。我无法找到具有持久性 window 的解决方案,该解决方案在没有 Invoke-Expression 的情况下对我有用。
如果有更好的方法在 PowerShell 中执行此操作,我会洗耳恭听!
{installMS32Bit}
如Mathias points out in a comment on the question, this statement doesn't call your function, it wraps it in a script block ({ ... }
)[1], which is a piece of reusable code (like a function pointer, loosely speaking), for later execution via &
, the call (execute) operator.
要调用你的函数,只需使用它的名字(在这里单独使用,假设没有参数通过):installMS32Bit
Invoke-Expression
should generally be avoided; definitely
此外,一般不需要通过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
默认情况下 在新的 window 中执行控制台应用程序(除非您指定 -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 将在一个新的 window 中执行以下 :
powershell.exe -File install.ps1
[1] 由于您没有将正在创建的脚本块分配给变量,因此它隐含地 output (打印到显示器,在没有重定向);脚本块按其文字内容进行字符串化,不包括封闭的 {
和 }
,因此字符串 installMS32Bit
将打印到显示器。