Thursday, July 3, 2014

Java Deployment with SCCM 2012 and PowerShell App Deployment Toolkit

OVERVIEW

Java is such a joy, isn't it?

I won't go into the trials and tribulations of potential Java version dependencies. That's another story in itself. This is to show one possible method of deployment that may or may not for your environment.

Starting with Java version 6 Update 10, the installer, by default, will try to overwrite previous Java versions. This was due to complaints from both the user and IT communities of having "too many" versions of Java installed. Older versions of Java did not remove previous versions. Systems had the potential of having dozens of Java versions installed (a reporting nightmare) requiring manual cleanup at some point in order to more easily manage "who has what".

A new parameter called STATIC was added so that the default behavior could be changed to not overwrite and keep all existing versions.


PowerShell App Deployment Toolkit

If you don't know about it, there's a nice little bundle of PowerShell scripts and configuration files that give you tons of options that can be useful. It's called the PowerShell App Deployment Toolkit.

https://psappdeploytoolkit.codeplex.com/

A couple of people put this together and it's a perfect toolkit to use if you are trying to deploy software where certain applications must be closed before they can install. They include a very easy guide to follow and get you started. Do not be daunted that this is all PowerShell based, especially if you don't know or feel comfortable with PowerShell. It's pretty simple to use and example scripts/scenarios are provided. The bonus is that you don't have to rely on a deployment tool such as SCCM. It can be run as a stand-alone package.

This has worked on Windows XP on up without having to upgrade PowerShell on XP systems, but it's something to consider if Windows XP is still in your environment. The highest version XP supports is PowerShell 2.0.

Review the App Deployment Toolkit documentation. Pay special attention to the examples provided. You can adjust some of the default behaviors set in the .XML files. In my environment, I modify the AppDeployToolkitConfig.xml file in the AppDeployToolkit folder and change the default path for the logs (<Toolkit_LogPath> and <MSI_LogPath>).


Build the Package

I create a folder for the package. In this case, the root folder is called 7Update55. Following the user App Deployment Toolkit guide, I copied the folder structure from the App Deployment Toolkit within the 7Update55 folder:



I then downloaded the latest Java version to a temp folder on my test machine. While you can use the .EXE file as it is, it's a little bit easier, in my opinion, to extract and use the .MSI file. To do that, start the install, but don't do anything beyond the Welcome screen. Once at the Welcome screen, open up Windows Explorer (My Computer) and browse to:

C:\Users\[UserName]\AppData\LocalLow\Sun\Java\[Java_Version] (where [UserName] is your user name and [Java_Version] is the version that was downloaded)

There will be two files...the .MSI and a  Data1.cab. BOTH files will be needed. Copy them into the Files folder as shown from the screenshot above, then cancel out of the Java install.

Go to the 7Update55 folder, right mouse click the Deploy-Application.ps1 file and choose Edit. PowerShell ISE should launch. Enter the relevant information in the # Variables: Application section. Some of the information is shown in the dialog boxes during the deployment.




Again, using the guide, determine the tasks and setting you want to do for each section (PRE-INSTALLATION, INSTALLATION, POST-INSTALLATION, and UNINSTALLATION). For this example, I'm doing the following:

PRE-INSTALLATION:

This is not going to be a silent deployment because user interaction is required. I set:

Show-InstallationProgress

I want to check to see if any browsers are running, and if they are, prompt the user to close them. I set:

Show-InstallationWelcome -CloseApps "iexplore,firefox,chrome,safari,opera" -PersistPrompt

Using the -PersistPrompt switch will make the dialog box re-appear every minute until the browsers are closed.






INSTALLATION:

This is where you set your command line for the install. Most vendors will have documentation on what switches and parameters are available.
To make the client aware of the installation progress, I set:
Show-InstallationProgress and add what I want the message box to say. Below that is the Execute-MSI command needed. Notice that I use the silent install switch "/qn". The client will see the PowerShell dialog box, NOT the Windows Installer progress bar.
For this particular package, I do not want the previous Java versions overwritten, so I also have the STATIC=1 parameter.




No steps were configured in the POST-INSTALLATION section.

UNINSTALLATION

I again want to check if any browsers are running before the removal. In this case, because it is being removed most likely by choice, I set the parameter, -CloseAppsCountdown to kill the browsers after 2 minutes if the client isn't there to do or ignores the dialog box. I then go on to set the uninstall command line switches.



Note that the path is the Product ID for this particular version of Java. The Product ID will be DIFFERENT if another version of Java is being packaged. To determine the Product ID, you can install manually on a test machine, then go into the test machine registry:


Determine Product ID for other versions of Java

32-bit Systems:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

64-bit Systems:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

Do a search for Java in the Uninstall folder and a subfolder should quickly be found. This folder name is the Product ID you need for the uninstall command.

Create SCCM 2012 Application

Fire up the SCCM Console and click on Software Library in the lower left corner.




Expand Application Management. Right mouse click Applications and choose Create Application





Even though there is an .MSI, we are going to use the Deploy-Application.EXE from the App Deployment Toolkit, so choose to Manually specify the application information and click Next.




In the General Information window, set the Name, Publisher, and Software version. If you want to use this in an SCCM Task Sequence, make sure the "Allow this application to be installed from the Install Application task sequence action without being deploy" option is checked. Setting the Owner and Support Contacts is optional. Click Next when done.




Setting the Application Catalog options will depend on your environment and if you are using a company portal or not. Click Next.



The Deployment Type is where we specify the package location and command line to install. Click the Add... button.


Change type to Script Installer in the drop down menu (it defaults to Windows Installer *.msi file). Changing the type will automatically select the Manually specify the deployment type information option. Click Next.


You can use the same name as before or simply call it "Install". I chose Java 7 Update 55 - Install. No language settings are necessary. Click Next.


Browse to the location of the 7Update55 folder, then set the commands for Installation and Uninstall. I also select the "Run installation and install program as 32-bit process on 64-bit clients" because this is a 32-bit package.


We now need to add a detection rule so SCCM can confirm if the install completed successfully. Because we are using the .MSI, we can use the Product ID as the detection method. Click Add Clause...


Change the Setting Type: to Windows Installer in the drop down list. Click Browser and point to the .MSI in the Files folder under 7Update55 and click OK. The Product code: field will automatically be populated. In most cases, this will be enough, however, if clients may have a newer version already installed, this version won't be necessary. Change the rule so the version is greater than or equal to the version being deployed. This will make it so only clients with 7 Update 54 or older will get the install. Anything newer will show as Already Compliant. Click OK, then click Next.


Because we need user interaction, we want to make sure the dialog boxes appear. Therefore, it must only install when a user is logged in. This is not a profile specific application, so we can choose to Install for system (uses the SYSTEM account priviledges) as the Install behavior. Logon requirement MUST BE set to Only when a user is logged on. Installation program visibility MUST BE set to Normal. "Allow users to view and interact with the program" MUST BE checked. Setting the Maximum allowed run time and Estimated installation time is optional but good practice.


Requirements are optional. You can set things like required disk space or OS versions if you choose.


There are no prerequisites needed for Java to install, so simply click Next.


The Summary will let you review your settings. Click Next to complete the build of the Application.

Before distributing content and deploying to collections, I test the install (copy the 7Update55 folder to a test machine) as a stand-alone (double-click Deploy-Application.EXE) and confirm it works as expected. Tweak settings as needed in the Deploy-Application.ps1 file and repeat testing. When satisfied with the results, remember to copy any changes back to your network source location of the package before distributing.

Once validated as a stand-alone install, you should be ready to distribute content and test the deployment to a test or pilot collection of systems.

Good luck!

21 comments:

  1. Great write up! Just the article I was looking for. One question, why didn't you use the remove-MSIApplications command?

    ReplyDelete
  2. For the same reason to use the Deploy-Application.EXE. The uninstall will also do a browser check and make sure they are closed before Java is removed. :-0

    ReplyDelete
  3. That's good to know, I wasn't aware the uninstall did that. :)

    ReplyDelete
  4. Thanks, it work nice.For the uninstall part I use powershell to find the java's version like this:

    $Javaversion = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Where {$_.PSChildName -like "{26A24AE4-*"} | select PSChildName
    $Javaversion = $Javaversion -replace("@{PSChildName","") -replace("=","") -replace("}}","}")
    Execute-MSI -Action Uninstall -Path $Javaversion

    ReplyDelete
  5. Another option to uninstall Java using the app deploy toolkit would be this: Get-InstalledApplication "java" | ? {$_.Publisher -like "*oracle*"} | % {Execute-Process msiexec.exe -Arguments "/x $($_.ProductCode) /qn" -WaitForMsiExec}

    ReplyDelete
    Replies
    1. Yes, this is another great option, however, this will remove all versions of Java, not just the version(s) installed. In some cases, you only want to remove what the package actually installed, leaving everything else intact. Thanks, Daniel!

      Delete
    2. I can't get Get-InstalledApplication to work. Please help!

      Delete
    3. I personally have not attempted to use the uninstall option suggested by Daniel. This is because it appears it will remove all versions of Java found. In the scenario where you need to keep specific versions installed, this would not be useful, but for a clean install, it would be. As for why it's not working, this article may help:

      https://psappdeploytoolkit.codeplex.com/discussions/571368

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Hi Jen

    This is a great write up. Many thanks for sharing.

    ReplyDelete
    Replies
    1. After testing I find I prefer to uninstall after the install to save on how many times this is deployed, makes no sense to have an uninstall rule for a different program imo.

      Defintely helped with deployment. But the uninstall should be to uninstall the correct version to the package not a different version.

      What are your thoughts on this?

      Delete
  8. I cannot get this to work with version 8.0.40, has anyone had any luck? Runs fine as standalone.

    ReplyDelete
  9. PowerShell Application Deployment Toolkit is now up to version 3.6. For some, a java config file had to be created and copied to the client machine before Java 8 would install. Using a configuration file is a new feature:

    http://docs.oracle.com/javase/8/docs/technotes/guides/install/config.html

    http://www.itninja.com/software/oracle/java-8/java-8-update-25

    I have not had this issue as of yet. My command line for Java 8 Update 40 has been changed to:

    Execute-MSI -Action Install -Path "jre1.8.0_40.msi" -Parameters "STATIC=1 AUTUPDATECHECK=0 ALLUSERS=1 DWUSINTERVAL=120 JAVAUPDATE=0 AUTO_UPDATE=0 WEB_JAVA=1 WEB_JAVA_SECURITY_LEVEL=H WEB_ANALYTICS=0 EULA=0 REBOOT=0 SPONSORS=0 /qn"

    We are still in a testing phase, but, so far, no issues with using the above command line.

    ReplyDelete
  10. Standalone package works fine. When I deploy with SCCM I'm not getting any messages, prompts or errors.

    ReplyDelete
  11. If you're deploying as an application, check the AppEnforce.log. If deploying as a package, check the execmgr.log. You might also consider adding the /l*v %TEMP%\java_install.log switch to see if it's Java itself failing as well. The detection method can also play a role if built as an application especially if the target machine has multiple versions of Java. You might need to do a file level detection instead of Product code. It all depends on what the logs reveal as the issue.

    ReplyDelete
  12. Going to do some testing today. May be an error in the appdeployment toolkit.

    https://psappdeploytoolkit.codeplex.com/workitem/172

    ReplyDelete
    Replies
    1. By default, the toolkit puts log files in C:\Windows\Logs\Software

      Delete
  13. Do you mind taking a look at my appEnforce.log?

    ReplyDelete
    Replies
    1. I recommend moving on to support forums at this point. This one is very helpful and your answer may already be there:

      https://social.technet.microsoft.com/Forums/en-US/configmanagerapps

      https://social.technet.microsoft.com/Forums/en-US/0e831d5e-b607-4cd5-8c9f-0e94eaca8d8f/deploying-java-8-u-40-with-powershell-application-deployment-toolkit-works-fine-locally-but-fails?forum=configmanagerapps

      Delete
  14. I figured it out. You show the install as "Deploy-Application.exe - Install", once I dropped the "- Install" it worked perfectly. May have been a change in syntax in later versions of PSAppdeploy.

    ReplyDelete
    Replies
    1. Ah, yes, that would do it. I have corrected the screenshot. Thank you!

      Delete