我对Jenkins中的PowerShell集成很新,我的脚本不会运行,因为(我相信)我需要PowerShell以64位执行。运行:
[Environment]::Is64BitProcess
在我的执行序列中产生false
然后我使用的cmdlet(Get-WindowsFeature
)显示为不被识别为cmdlet等。任何方式执行64位PowerShell脚本?
谢谢!
答案 0 :(得分:12)
Jenkins通常会调用powershell.exe
的正确版本。但是,执行程序/从属进程必须运行64位JRE,以便PowerShell也可以在64位模式下运行。
使用以下Powershell脚本的简单测试人员项目可以显示上述32位与64位性质:
$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
控制台输出示例(为清晰起见,额外的空行):
[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 ... 安装64位JRE,并将Jenkins配置为64位。
我使用chocolatey通过“管理员”PowerShell安装了一个相当新的JRE:
首先,安装chocolatey:
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
寻找可用的最新版本https://chocolatey.org/packages?q=java(chocolatey有相同的多个包,通常不完全保持最新)。
然后,安装JRE(使用具有更高JRE编号的JRE):
choco install -y javaruntime
或者:
choco install -y jre8
最后,我编辑了jenkins.xml
配置,以便它可以使用64位JRE而不是内置JRE运行。
更改:
<executable>%BASE%\jre\bin\java</executable>
收件人(根据您的实例设置路径):
<executable>C:\Program Files\Java\jre1.8.0_66\bin\java</executable>
这个应该是一个“永远新鲜”的符号链接(由系统更新处理),它应该允许你的Jenkins实例存活 重新启动和更新 事件:
<executable>C:\ProgramData\Oracle\Java\javapath\java.exe</executable>
然后我重新启动了詹金斯。 Powershell执行唤醒了64位的威力。 注意:我正在使用单个Jenkins实例,它同时作为“服务器”和“执行从属”执行双重任务。对于完全自治的从属设备,我认为做任何事情都可以使64位模式的从属代理进程取得类似的成功。
完全自动化?根据巧克力“jre8”软件包文档,使用命令行开关,如果需要完全自动化的非交互式步骤,甚至可以强制JRE的固定目标路径,并排除32位和/或64位版本。 https://chocolatey.org/packages/jre8
答案 1 :(得分:4)
我对詹金斯并不熟悉,但似乎它本身就是一个32位进程。
您可以指定PowerShell可执行文件的位置吗?如果是这样,请尝试使用此路径:
C:\Windows\SysNative\WindowsPowerShell\v1.0\powershell.exe
如果你不能这样做,那么你可以在你的&#34;执行序列&#34;中执行代码。与Invoke-Command
:
Invoke-Command -ComputerName . -ScriptBlock { [Environment]::Is64BitProcess }
scriptblock中的所有代码都将在一个单独的64位进程中运行,结果将被序列化并返回。
在32位Windows操作系统上,系统文件夹为C:\Windows\System32
。
在64位Windows操作系统上,64位系统文件夹也是C:\Windows\System32
。但是,64位Windows安装上的32位进程的系统文件夹实际上是C:\Windows\SysWOW64
。
为了兼容性,64位操作系统上的32位进程可以调用C:\Windows\System32
透明地重定向到C:\Windows\SysWOW64
,这是该过程所不知道的。
要启用32位进程以在64位操作系统上引用 real System32
,您可以使用C:\Windows\SysNative
。
由于PowerShell具有32位和64位版本,并且它位于系统文件夹中,因此您需要使用上述规则来引用正确的可执行文件,具体取决于您是从64位还是32位调用它位过程。
典型情况(您想要调用相同位数的版本)最简单(只需调用powershell.exe
或通过System32
引用它),但如果您想引用< em>其他版本。
Invoke-Command
方法 Invoke-Command
cmdlet允许您运行代码,通常在另一台计算机上运行,但您也可以在同一台计算机上运行它。这将产生一个完全独立的进程,任何输出都会被序列化并发送回调用进程。
此方法的警告是您必须通过Enable-PSRemoting
或Group Policy(无耻的自我插件)在计算机上启用PowerShell远程处理。
无论调用者的操作系统如何,在64位计算机上连接的默认配置文件(Microsoft.PowerShell
)都是64位版本的PowerShell。
顺便提一下,如果您想使用Invoke-Command
连接到32位版本,可以通过明确指定配置文件Microsoft.PowerShell32
来实现。
答案 2 :(得分:0)
好的,所以答案非常简单,但同时令人抓狂。基本上,两个Powershell路径(x86和x64)中都不存在模块,因此将模块复制到32位PowerShell环境可以解决问题。
答案 3 :(得分:0)
更多建议:
这对我有用!