I am doing local Chef dev on my Windows 8.1 laptop and use VirtualBox 5.1.24 for VMs. I want to use Jenkins (v2.73.2) to run jobs that will automate the restoring of VM snapshots and running of kitchen converge, test and repeat.
I have added the VirtualBox Plugin but it doesn't let me add a node (I recall seeing somewhere that v2.73.2 of Jenkins is not supported).
I wrote some Powershell to do what I want and so after installing PowerShell Plugin created a pipeline with following PowerShell to test it:
& "C:\Program Files\Oracle\VirtualBox\vboxmanage.exe" startvm "W2008_21_06_B"
(which works in PS ISE), but fails in Jenkins job:
Building on master in workspace C:\Program Files (x86)\Jenkins\workspace\vbox
[vbox] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\windows\TEMP\jenkins7025720492184266246.ps1'"
vboxmanage.exe: error: Could not find a registered machine named 'W2008_21_06_B'
vboxmanage.exe: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee IUnknown
vboxmanage.exe: error: Context: "FindMachine(Bstr(pszVM).raw(), machine.asOutParam())" at line 573 of file VBoxManageMisc.cpp
Build step 'Windows PowerShell' marked build as failure
Finished: FAILURE
What trick am I missing please?
Regards
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!
Environment
Jenkins on Windows (mine happens to run as a service)
plus Powershell plugin (for running Powershell scripts as "build steps")
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
Solution
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.
Explanations
Paths
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 Method
The 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.
OK, so the answer was pretty simple, yet maddening all at once. Basically, the module(s) didn't exist in both of the Powershell paths (x86 and x64), so copying the modules over to the 32-bit powershell environment fixed the issue.
further suggestions:
check path of 32bit-JRE, remove path or uninstall 32bit-JRE --
also swapping path-position with 64bit-JRE might work
check path(s) of PowerShell, remove path of 32bit PowerShell
(..\SysWOW64\..) and add the other one to the path (..\System32\..)
This worked for me!
I am installing a program through SCCM2012 SP2 with a PowerShell Script and it fails with an install shield ResponseCode -3, running the Powershell script manually from C:\windows\ccmcache#\ succeeds though...
This is my command line (it works for dozens of other scripts - including installshield packaged scripts)...
"%WINDIR%\sysnative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy RemoteSigned -file .\InstallTigerpaw.ps1
If it's the system error code 3, it means 'File Not Found'. Running manually from cache is different with executing by CM agent. Below is something I will take into consideration when try to deploy a PowerShell Script using Program.
First,
To deploy a script using Configuration Manager, I always test it first by running it manually under System Context, which is the same context that CM deployments run under. I use PSExec tool to open a new command prompt under system context by running psexec /s cmd.exe in a common command prompt.
Second,
The command you use in the program. In your case, use Sysnative only when you intend to access system32 folder on a 64 bit operating system. If not, then don't need it.
Third,
The Execution Policy. Microsoft allows you to temporarily bypass the execution policy to get work done, that's a reason that I usually use Bypass. Example like:
PowerShell.exe -ExecutionPolicy Bypass -File ".\PowerShellScriptFileName.ps1"
Most of the time the deployment goes fine on clients. In case of problems, I will look at client side log, execmgr.log.
In some cases, we may need to set 'Only when a user is logged on', 'Run with administrative rights' for specific needs of running scripts.
I'm trying to administer PowerShell scripts on a central shared location. At the moment the .ps1 scripts are all stored on many different servers.
The scripts are used in Scheduled Tasks with the 'Action' specifics:
Program/script: powershell.exe
Add arguments (optional): G:..\scriptABC.ps1
Start in (optional): C:\Windows\System32\WindowsPowerShell\v1.0\
Now the goal is to have them all on a shared location:
\\domain\root..\scripts\scriptABC.ps1
Problem:
When I update the 'Add arguments' field to "\\domain\root..\scripts\scriptABC.ps1" and try to start the task, it'll say Running for a few seconds and than Ready again, but nothing happened. So it works like a charm when a local drive is specified, but not when a UNC path is specified.
Additional info:
Working on Windows Server 2012 R2
Any thoughts?
Check out the following link
https://community.spiceworks.com/how_to/17736-run-powershell-scripts-from-task-scheduler
Also the machine running the task will need to have permission to access the file on the network
I wrote a little PowerShell script that invokes different MSI files to install software. Sometimes I got the following error from Windows Installer:
Another program is being installed. Please wait until that installation is complete, and then try installing this software again.
How could I prevent this error before I invoke the MSI files? I tried to associate this with the process TrustedInstaller. I thought that the process would come up when the PC is installing something that blocks my installation. But unfortunately, sometimes my installations work fine although the process is running. Is there a definitive indication which could be caught with PS?
You want to see if the _MSIExecute Mutex is set.
Simply checking for a running msiexec.exe won't tell you because a) msiexec could be processing a UI sequence which doesn't block you or b) msiexec could have finished an install and be waiting for 10 minutes to spin down it's service.
try
{
$Mutex = [System.Threading.Mutex]::OpenExisting("Global\_MSIExecute");
$Mutex.Dispose();
Write-Host "An installer is currently running."
}
catch
{
Write-Host "An installer is not currently runnning."
}
In the meantime I found the following approach: Whenever an MSI based installation is currently running a specific regkey is set. This is more reliable than trusting any processes that are active at this time. The regkey is only set when an installation is running.
Test-Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Installer\InProgress"