I'm pretty new to powershell integration in Jenkins and my scripts won't run because (I believe) I need powershell to be executed in 64 bit. Running:
[Environment]::Is64BitProcess
in my execution sequence yields false
an then a cmdlet that I use (Get-WindowsFeature
) is shown as not recognized as a cmdlet, etc. Any way to execute 64 bit powershell scripts?
Thanks!
The 64-bit version of PowerShell (the one that 64-bit Windows opens by default) is located under: “C:\Windows\SysWOW64\WindowsPowerShell\v1. 0.” To run the program as administrator, right-click on powershell.exe and then choose the “Run as administrator” option.
When you run Windows PowerShell, the 64-bit version runs by default. However, you might occasionally need to run Windows PowerShell (x86), such as when you're using a module that requires the 32-bit version or when you're connecting remotely to a 32-bit computer.
Jenkins PowerShell PluginIntegrates with PowerShell by allowing you to directly write PowerShell scripts into the text box in Jenkins. Other than that, this plugin works pretty much like the standard shell script support.
Jenkins will typically call upon the correct version of powershell.exe
. However, the executor/slave process must be running a 64-bit JRE so that PowerShell can also operate in 64-bit mode.
A simple tester project with the following Powershell script can show the above 32-bit vs 64-bit nature:
$env:Path # Path will have the right Powershell available
[intptr]::size # outputs: 4 = 32-bit, 8 = 64-bit
Stop-WebAppPool FOOBAR # fails when 32-bit, succeeds when 64-bit
Console output example (extra blank lines for clarity):
[Powershell Test] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Windows\TEMP\hudson123456789.ps1'"
C:\Windows\system32;C:\Windows;C:\Windows\System32\WindowsPowerShell\v1.0\
4
Stop-WebAppPool : Retrieving the COM class factory for component with CLSID
{688EEEE5-6A7E-422F-B2E1-6AF00DC944A6} failed due to the following error:
80040154 Class not registered (Exception from HRESULT: 0x80040154
(REGDB_E_CLASSNOTREG)).
At C:\Windows\TEMP\hudson123456789.ps1:7 char:1
tl;dr... Install 64-bit JRE, and configure Jenkins to be 64-bit.
I used chocolatey to install a fairly recent JRE, via "Administrator" PowerShell:
First, install chocolatey:
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
Looked for the latest version available https://chocolatey.org/packages?q=java (chocolatey has multiple packages for the same thing, often not kept fully up to date).
Then, install JRE (using the one with the higher JRE number):
choco install -y javaruntime
Or:
choco install -y jre8
Finally, I edited my jenkins.xml
configuration so that it would run using the 64-bit JRE instead of the built-in JRE.
Changed:
<executable>%BASE%\jre\bin\java</executable>
To (set the path as appropriate for your instance):
<executable>C:\Program Files\Java\jre1.8.0_66\bin\java</executable>
This one should be an "always fresh" symlink (handled by system updates) that ought to allow your Jenkins instance to survive Restart and Update events:
<executable>C:\ProgramData\Oracle\Java\javapath\java.exe</executable>
Then I restarted Jenkins. Powershell execution woke up to the might of 64-bits. Note: I am using a single Jenkins instance that does double duty as the "server" and "execution slave" at the same time. For fully autonomous slaves, I would suppose doing whatever to get the slave-agents processes in 64-bit mode would result in a similar success.
Full automation? According to the chocolatey "jre8" package documentation, using command line switches, it's even be possible to force fixed destination paths for JRE, and exclude 32-bit and/or 64-bit editions, if fully automated non-interactive steps are needed. https://chocolatey.org/packages/jre8
I am not familiar with Jenkins, but it seems like it's a 32 bit process itself.
Can you specify the location of the PowerShell executable? If so, try to use this path:
C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe
If you can't do that, then you might be able to do it in code in your "execution sequence" with Invoke-Command
:
Invoke-Command -ComputerName . -ScriptBlock { [Environment]::Is64BitProcess }
All the code in the scriptblock will be run in a separate 64 bit process and the results will be serialized and returned.
On a 32 bit Windows OS, the system folder is C:\Windows\System32
.
On a 64 bit Windows OS, the 64 bit system folder is also C:\Windows\System32
. But the system folder for 32 bit processes on a 64 bit Windows installation is in fact C:\Windows\SysWOW64
.
For compatibility, a 32 bit process on a 64 bit OS will have any calls to C:\Windows\System32
transparently redirected to C:\Windows\SysWOW64
, unbeknownst to the process.
To enable a 32 bit process to reference the real System32
on a 64 bit OS, you can you use C:\Windows\SysNative
.
Since PowerShell has a 32 bit and a 64 bit version, and it lives inside the system folders, you need to use the above rules to reference the correct executable depending on whether you're calling it from a 64 or 32 bit process.
The typical scenario (you want to call the version of the same bitness) is easiest (just call powershell.exe
or reference it via System32
), but it gets hairy if you want to reference the other version.
Invoke-Command
MethodThe Invoke-Command
cmdlet lets you run code, typically on another computer, but you can run it on the same computer as well. This will spawn a completely separate process, and any output gets serialized and sent back to the calling process.
The caveat to this method is that you must enable PowerShell remoting on the machine, via Enable-PSRemoting
or Group Policy (shameless self plug).
The default profile (Microsoft.PowerShell
) that you connect to on a 64 bit machine will be a 64 bit version of PowerShell, regardless of the OS of the caller.
Incidentally, if you wanted to use Invoke-Command
to connect to a 32 bit version, you could do so by explicitly specifying the profile Microsoft.PowerShell32
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With