Функция PowerShell не работает должным образом - PullRequest
1 голос
/ 18 февраля 2020

У меня есть любопытный случай, когда я не могу понять причину ...

Пожалуйста, знайте, что я новичок в 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 file:

    # 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 ...

Мне нравится видеть прогресс и нравится иметь вторичный windows открыто для мониторинга запуска нового процесса. Мне не удалось найти решение с постоянным окном, которое помогло бы мне сделать это без Invoke-Expression.

Если есть лучший способ сделать это в PowerShell, я весь в ушах!

1 Ответ

3 голосов
/ 18 февраля 2020

{installMS32Bit}

Как Матиас указывает в комментарии к вопросу, это утверждение не вызывает вашу функцию, он оборачивает его в блок сценария ({ ... }) [1] , который представляет собой фрагмент кода для повторного использования (например, указатель на функцию, если говорить свободно) , для позже выполнение через &, оператор вызова (выполнения) .

Для вызова вашей функции, просто используйте его имя (само по себе здесь, учитывая, что нет аргументов для передачи): installMS32Bit

Invoke-Expression, как правило, следует избегать ; определенно не используйте его для вызова внешней программы , как в ваших попытках.

Кроме того, обычно нет необходимости вызывать внешнюю программу через 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'

Мне нравится наблюдать за прогрессом, и мне хотелось бы, чтобы дополнительный windows был открыт для мониторинга запуска нового процесса. Мне не удалось найти решение с постоянным окном, которое помогло бы мне сделать это без выражения-выражения.

(Вкл. Windows), Start-Process по умолчанию запускает консольное приложение в новом окне (если вы не укажете -NoNewWindow), асинхронно (если не указано -Wait).

Вы не можете передать .ps1 script напрямую до Start-Process (он будет рассматриваться как документ для открытия, а не исполняемый для вызова), но вы можете передать его CLI PowerShell через параметр -File:

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

Выше приведено краткое обозначение:

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

То есть PowerShell выполнит следующее в новом окне :
powershell.exe -File install.ps1


[1] Поскольку вы не назначаете блок сценария, создаваемый переменной, он неявно вывод (выводится на дисплей при отсутствии перенаправления); блок скрипта преобразуется по буквальному содержанию, исключая { и }, поэтому строка installMS32Bit будет выводиться на дисплей.

...