Search code examples
powershellnsiswindows-server-2008-r2

How to call PowerShell in NSIS


I am trying to run PowerShell in NSIS. when I run the NSIS script:

!include "x64.nsh"

Name "nsExec Test"

OutFile "nsExecTest.exe"

ShowInstDetails show

Section "Output to variable"

    nsExec::ExecToStack 'powershell -Command "& {Import-Module }" ServerManager'
    Pop $0 # return value/error/timeout
    Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
    DetailPrint '"ImportModules" printed: $1'
    DetailPrint "       Return value: $0"

    nsExec::ExecToStack 'powershell -Command "& {Get-WindowsFeature}" Desktop-Experience'
    Pop $0 # return value/error/timeout
    Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
    DetailPrint '"GetWindowsFeature" printed: $1'
    DetailPrint "       Return value: $0"
SectionEnd

When it executed to "Import-Module ServerManager", The PowerShell was started up(It can be seen in TaskManager processes). But nsExecTest.exe was hanging over.

I have googled this problem, and found a workaround for Java. https://blogs.oracle.com/vaibhav/entry/not_as_easy_as_we

Anyone has ideas for this problem in NSIS?

Updated: I simplify my test script.

!include "x64.nsh"

Name "nsExec Test"
OutFile "nsExecTest.exe"
ShowInstDetails show

Section "Output to variable"
${If} ${RunningX64}
    ${DisableX64FSRedirection}

    nsExec::ExecToStack 'powershell.exe "& "Import-Module ServerManager"'
    Pop $0 # return value/error/timeout
    Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
    DetailPrint '"ImportModules" printed: $1'
    DetailPrint " Return value: $0"
    DetailPrint ""

    ${EnableX64FSRedirection}
${Else}
${EndIf}
SectionEnd

Solution

  • As far as I found out, AaronLS's answer didn't work for me, I found two workarounds for this problem, related to a bug in PowerShell v2 reported here (but never fixed):

    • Upgrade to PowerShell v3
    • Run the script from a file in NSIS, and specify inputformat none. For a very strange reason you have to leave two spaces before the last quote of nsExec::ExecToStack:

      SetOutPath "$pluginsdir\NSISTemp"
      File script.ps1
      nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "$pluginsdir\NSISTemp\script.ps1"  '
      

    Using the macros I've written here, it is just a matter of ${PowerShellExec} "echo 'hello powershell'".