-
-
Save dotps1/492023ebd737f9cc46aa to your computer and use it in GitHub Desktop.
Param ( | |
[Parameter( | |
Mandatory = $true | |
)] | |
[String] | |
$SourcePackageCreationPath, | |
[Parameter( | |
Mandatory = $true | |
)] | |
[String] | |
$ComputerName, | |
[Parameter()] | |
[PSCredential] | |
$Credential, | |
[Parameter( | |
Mandatory = $true | |
)] | |
[String] | |
$SiteCode, | |
[Parameter()] | |
[String] | |
$ApplicationFolder, | |
[Parameter()] | |
[System.Security.Cryptography.X509Certificates.X509Certificate2] | |
$CodeSigningCertificate | |
) | |
#region Main | |
$ErrorActionPreference = 'Stop' | |
if (($installers = Invoke-JavaDownloadAndMsiExtraction -Verbose:$VerbosePreference) -eq $null) { | |
throw $_ | |
} | |
# Installer script to be generated in package directory. | |
$installScript = @" | |
`$location = Split-Path -Path `$(`$global:MyInvocation.MyCommand.Path) | |
`$architecture = (Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' -Name 'PROCESSOR_ARCHITECTURE').PROCESSOR_ARCHITECTURE | |
# Uninstall existing versions of Java $($installers.VersionInfo.ProductMajorPart). | |
foreach (`$install in (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { `$_.DisplayName -match 'Java $($installers.VersionInfo.ProductMajorPart) Update \d+' })) { | |
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x `$(`$install.PSChildName) /quiet" -Wait | |
} | |
if (-not (Test-Path -Path "`$env:ProgramData\Oracle\Java")) { | |
New-Item -Path "`$env:ProgramData\Oracle\Java" -ItemType Directory -Force | Out-Null | |
} | |
# Ensure Java Settings Config file exists in the ProgramData Directory. | |
Copy-Item -Path `${location}\java.settings.cfg -Destination "`$env:ProgramData\Oracle\Java" -Force | |
if (`$architecture -eq 'AMD64') { | |
foreach (`$install in (Get-ItemProperty -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { `$_.DisplayName -match 'Java $($installers.VersionInfo.ProductMajorPart) Update \d+' })) { | |
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x `$(`$install.PSChildName) /quiet" -Wait | |
} | |
} | |
try { | |
# Install x86. | |
Start-Process -FilePath 'msiexec.exe' -ArgumentList "/i `${location}\x86.msi INSTALLCFG=`${location}\java.settings.cfg /quiet" -Wait -ErrorAction Stop | |
# Install x64 on compatiable systems. | |
if (`$architecture -eq 'AMD64') { | |
Start-Process -FilePath 'msiexec.exe' -ArgumentList "/i `${location}\x64.msi INSTALLCFG=`${location}\java.settings.cfg /quiet" -Wait -ErrorAction Stop | |
} | |
exit 0 | |
} catch { | |
exit 1 | |
} | |
"@ | |
# Java installer config file to be generated in package directory. | |
$installSettings = @' | |
AUTO_UPDATE=0 | |
REBOOT=0 | |
NOSTARTMENU=1 | |
'@ | |
# Create output folder for package. | |
try { | |
Write-Verbose -Message "Creating output directory: $SourcePackageCreationPath\$($installers.VersionDisplayName)." | |
$package = New-Item -Path $SourcePackageCreationPath -Name $installers.VersionDisplayName -ItemType Directory -Force -ErrorAction Stop | |
} catch { | |
throw $_ | |
} | |
# Copy installers to folder. | |
try { | |
Write-Verbose -Message "Copying $($installers.x86Msi.FullName) to $($package.FullName)\x86.msi." | |
Copy-Item -Path $installers.x86Msi.FullName -Destination "$($package.FullName)\x86.msi" -Force -ErrorAction Stop | |
Write-Verbose -Message "Copying $($installers.x64Msi.FullName) to $($package.FullName)\x64.msi." | |
Copy-Item -Path $installers.x64Msi.FullName -Destination "$($package.FullName)\x64.msi" -Force -ErrorAction Stop | |
} catch { | |
throw $_ | |
} | |
# Extract install script and settings file to package folder. | |
try { | |
Write-Verbose -Message "Extracting Install-Java.ps1 to $($package.FullName)." | |
Out-File -FilePath "$($package.FullName)\Install-Java.ps1" -InputObject $installScript -Encoding ascii -NoNewline -Force -ErrorAction Stop | |
# Sign the extracted script. | |
if ($PSBoundParameters.ContainsKey('CodeSigningCertificate')) { | |
try { | |
Write-Verbose -Message "Signing $($package.FullName)\Install-Java.ps1 with $($CodeSigningCertificate.Subject)." | |
Set-AuthenticodeSignature -Certificate $CodeSigningCertificate -FilePath "$($package.FullName)\Install-Java.ps1" -ErrorAction Stop | Out-Null | |
} catch { | |
throw $_ | |
} | |
} | |
Write-Verbose -Message "Extracting java.settings.cfg to $($package.FullName)." | |
Out-File -FilePath "$($package.FullName)\java.settings.cfg" -InputObject $installSettings -Encoding ascii -NoNewline -Force -ErrorAction Stop | |
} catch { | |
throw $_ | |
} | |
#region CreateSccmApplicaion. | |
try { | |
$currentVerbosePreference = $VerbosePreference | |
$VerbosePreference = 'SilentlyContinue' | |
$sessionParams = @{ | |
ComputerName = $ComputerName | |
} | |
if ($PSBoundParameters.ContainsKey('Credential')) { | |
$sessionParams.Add('Credential', $Credential) | |
} | |
$session = New-PSSession @sessionParams | |
Invoke-Command -Session $session -ScriptBlock { | |
Import-Module -Name "$(Split-Path $Env:SMS_ADMIN_UI_PATH)\ConfigurationManager.psd1" -Verbose:$false | |
Set-Location -Path "$(Get-PSDrive -PSProvider CMSite):\" | |
} | |
Import-PSSession -Session $session -Module ConfigurationManager -AllowClobber | Out-Null | |
$VerbosePreference = $currentVerbosePreference | |
} catch { | |
throw $_ | |
} | |
if (Get-CMApplication -Name $installers.VersionInfo.ProductName) { | |
throw "The application $($installers.VersionInfo.ProductName) already exists." | |
} | |
$applicationParams = @{ | |
Name = $installers.VersionInfo.ProductName | |
Description = "$($installers.VersionInfo.ProductName)" | |
SoftwareVersion = $installers.VersionInfo.ProductVersion | |
LocalizedName = "$($installers.VersionInfo.ProductName)" | |
LocalizedDescription = "Installs and configures $($installers.VersionInfo.ProductName) for both x86 and x64 Systems. Please restart any open browsers after running this install." | |
} | |
try { | |
Write-Verbose -Message 'Creating application.' | |
$application = New-CMApplication @applicationParams | |
} catch { | |
throw $_ | |
} | |
$deploymentParams = @{ | |
ApplicationName = $application.LocalizedDisplayName | |
ProductCode = "{$($installers.x86MsiProductCode)}" | |
DeploymentTypeName = "$($installers.VersionInfo.ProductName) - Script Installer" | |
InstallCommand = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\Install-Java.ps1" | |
ContentLocation = $package.FullName | |
EstimatedRuntimeMins = 5 | |
MaximumRuntimeMins = 15 | |
LogonRequirementType = 'WhereOrNotUserLoggedOn' | |
UserInteractionMode = 'Hidden' | |
} | |
try { | |
Write-Verbose -Message 'Creating deployment type.' | |
$deployment = Add-CMScriptDeploymentType @deploymentParams | |
} catch { | |
throw $_ | |
} | |
if ($PSBoundParameters.ContainsKey('ApplicationFolder')) { | |
try { | |
Write-Verbose -Message "Moving application to appropriate folder." | |
$applicationID = Get-WmiObject -Namespace Root\SMS\Site_$SiteCode -Class SMS_ApplicationLatest -Filter "LocalizedDisplayName='$($installers.VersionInfo.ProductName)'" -ComputerName $ComputerName | |
$targetFolderID = Get-WmiObject -Namespace Root\SMS\Site_$SiteCode -Class SMS_ObjectContainerNode -Filter "Name='$($ApplicationFolder)' and ObjectType='6000'" -ComputerName $ComputerName | |
$currentFolderID = 0 | |
$wmiConnection = [WMIClass]"\\$($ComputerName)\root\SMS\Site_$($SiteCode):SMS_objectContainerItem" | |
$moveItem = $wmiConnection.psbase.GetMethodParameters("MoveMembers") | |
$moveItem.ContainerNodeID = $currentFolderId | |
$moveItem.InstanceKeys = $applicationID.ModelName | |
$moveItem.ObjectType = 6000 | |
$moveItem.TargetContainerNodeID = $targetFolderID.ContainerNodeID | |
$wmiConnection.psbase.InvokeMethod("MoveMembers",$moveItem,$null) | Out-Null | |
} catch { | |
throw $_ | |
} | |
} | |
Write-Verbose -Message 'Application created succsesfully in the root application folder.' | |
#endregion CreateSccmApplication | |
#endregion Main |
<# | |
.SYNOPSIS | |
Gets the product code from a Windows Installer Database. | |
.DESCRIPTION | |
Opens a Windows Installer Database (.msi) and querys for the product code. | |
.INPUTS | |
System.String. | |
.OUTPUTS | |
System.Guid. | |
.EXAMPLE | |
PS C:\> Get-MsiProductCode -Path C:\my.msi | |
.LINK | |
http://dotps1.github.io | |
#> | |
Function Get-MsiProductCode { | |
[OutputType([Guid])] | |
Param ( | |
[Parameter( | |
Mandatory = $true, | |
ValueFromPipeLine = $true | |
)] | |
[String] | |
$Path | |
) | |
try { | |
$windowsInstaller = New-Object -com WindowsInstaller.Installer | |
$database = $windowsInstaller.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $windowsInstaller, @((Get-Item -Path $Path).FullName, 0)) | |
$view = $database.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $database, ("SELECT Value FROM Property WHERE Property = 'ProductCode'")) | |
$view.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $view, $null) | |
$record = $view.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $view, $null) | |
return $($record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 1)) | |
$view.GetType().InvokeMember('Close', 'InvokeMethod', $null, $view, $null) | |
[Void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($windowsInstaller) | |
} catch { | |
throw $_ | |
} | |
} |
<# | |
.SYNOPSIS | |
Downloads and extracts the latest version of Java Runtime Environment. | |
.DESCRIPTION | |
Download the x86 and x64 offline installer executables for the Java Website. | |
Runs each exeacuatble, which then extracts the MSIs to the current users APPDATA. | |
.INPUTS | |
None. | |
.OUTPUTS | |
System.Management.Automation.PSCustomObject. | |
.EXAMPLE | |
Invoke-JavaDownloadAndExtraction | |
.EXAMPLE | |
Invoke-JavaDownloadAndExtraction -Verbose | |
.NOTES | |
The current Java Installer Staging directory will be removed then recreated. | |
.LINK | |
http://www.java.com/en/download/manual.jsp | |
#> | |
Function Invoke-JavaDownloadAndMsiExtraction { | |
[CmdletBinding()] | |
[OutputType( | |
[PSCustomObject] | |
)] | |
Param ( | |
) | |
Begin { | |
# Verify Admin Rights before running. | |
if (-not ([System.Security.Principal.WindowsPrincipal][System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]'Administrator')) { | |
throw 'This cmdlet cannot be used in this context. Restart PowerShell using the Run As Administrator option.' | |
} | |
} | |
Process { | |
# Download offline installers. | |
$downloadPage = Invoke-WebRequest -Uri 'http://www.java.com/en/download/manual.jsp' | |
$x86Download = ($downloadPage.Links | Where-Object { $_.innerText -eq 'Windows Offline' }).href | |
$x64Download = ($downloadPage.Links | Where-Object { $_.innerText -eq 'Windows Offline (64-Bit)' }).href | |
$downloader = New-Object -TypeName System.Net.WebClient | |
try { | |
Write-Verbose -Message "Downloading Java x86 Offline Installer. URL: $x86Download" | |
$downloader.DownloadFile($x86Download, "$env:USERPROFILE\Downloads\Java_x86.exe") | |
Write-Verbose -Message "Downloading Java x64 Offline Installer. URL: $x64Download" | |
$downloader.DownloadFile($x64Download, "$env:USERPROFILE\Downloads\Java_x64.exe") | |
$x86Exe = Get-Item -Path "$env:USERPROFILE\Downloads\Java_x86.exe" | |
$x64Exe = Get-Item -Path "$env:USERPROFILE\Downloads\Java_x64.exe" | |
} catch { | |
throw $_ | |
} | |
# Delete Java Install staging directory. | |
try { | |
$stagingDirectory = "$env:USERPROFILE\AppData\LocalLow\Oracle" | |
if (Test-Path -Path $stagingDirectory) { | |
Write-Verbose -Message "Removing existing Java Install Staging Directory: $stagingDirectory." | |
Remove-Item -Path $stagingDirectory -Recurse -Force -ErrorAction Stop | |
} | |
# Recreate the directory to make sure the path exists for the get child item. | |
Write-Verbose -Message "Creating new Java Install Staging Directory: $stagingDirectory." | |
$stagingDirectory = New-Item -Path $stagingDirectory -Name 'Java' -ItemType Directory -Force | |
} catch { | |
throw $_ | |
} | |
# Trigger x86 .exe to extract msi to install staging directory. | |
Write-Verbose -Message "Starting Java 32-bit Installer to extract msi to $stagingDirectory." | |
Write-Warning -Message 'DO NOT CLOSE THE JAVA INSTALLER WINDOW, IT WILL CLOSE IT SELF AFTER THE MSI IS EXTRACTED.' | |
Start-Process -FilePath $x86Exe.FullName | |
do { | |
$x86Msi = Get-ChildItem -Path "$($stagingDirectory.FullName)\jre*" -Filter 'jre*.msi' -Recurse | |
Start-Sleep -Milliseconds 2500 | |
} until ($x86Msi.Exists) | |
Write-Verbose -Message "32-bit msi extracted, terminating Java processes." | |
do { | |
$processes = Get-WmiObject -Class Win32_Process | Where-Object { $_.Path -match 'Java' } | |
foreach ($process in $processes) { | |
Invoke-WmiMethod -InputObject $process -Name Terminate | Out-Null | |
} | |
Start-Sleep -Milliseconds 2500 | |
} until ($processes.Count -eq 0) | |
Write-Verbose -Message "Starting Java 64-bit Installer to extract msi to $stagingDirectory." | |
Write-Warning -Message 'DO NOT CLOSE THE JAVA INSTALLER WINDOW, IT WILL CLOSE IT SELF AFTER THE MSI IS EXTRACTED.' | |
Start-Process -FilePath $x64Exe.FullName | |
do { | |
$x64Msi = Get-ChildItem -Path "$($stagingDirectory.FullName)\jre*x64" -Filter 'jre*.msi' -Recurse | |
Start-Sleep -Milliseconds 2500 | |
} until ($x64Msi.Exists) | |
Write-Verbose -Message "64-bit msi extracted, terminating Java processes." | |
do { | |
$processes = Get-WmiObject -Class Win32_Process | Where-Object { $_.Path -match 'Java' } | |
foreach ($process in $processes) { | |
Invoke-WmiMethod -InputObject $process -Name Terminate | Out-Null | |
} | |
Start-Sleep -Milliseconds 2500 | |
} until ($processes.Count -eq 0) | |
[PSCustomObject]$psCustomObject = @{ | |
x86Msi = $x86Msi | |
x86MsiProductCode = [Guid]::New((Get-MsiProductCode -Path $x86Msi.FullName)) | |
x64Msi = $x64Msi | |
x64MsiProductCode = [Guid]::New((Get-MsiProductCode -Path $x64Msi.FullName)) | |
VersionDisplayName = $x86Msi.PSParentPath.Substring($x86Msi.PSParentPath.LastIndexOf([System.IO.Path]::DirectorySeparatorChar) +1) | |
VersionInfo = $x86Exe.VersionInfo | |
} | |
} | |
End { | |
Write-Verbose -Message "Deleting Java Offline Installers." | |
Remove-Item -Path $x86Exe.FullName -Force | |
Remove-Item -Path $x64Exe.FullName -Force | |
return $psCustomObject | |
} | |
} |
dotps1
commented
Aug 31, 2015
- Download both x86 and x64 versions of the Java Offline Installer.
- Run the x86 exe which extracts the msi to the current users Application Data. (This will show the Java installer windows, DO NOT CLOSE THIS WINDOW! The script will do so at the appropriate time.)
- After the msi exists, terminate all the running java process.
- Run the x64 exe which extracts the msi to the current users Application Data. (This will show the Java installer windows, DO NOT CLOSE THIS WINDOW! The script will do so at the appropriate time.)
- After the msi exists, terminate all the running java process.
- Create the package directory specified in the SoucesPath.
- Copy both msi's to that path.
- Extract the Installer Script to the package directory.
- Sign the installer script.
- Extract the java installer properties file to the package directory.
- Import the Config Manager assemblies, (I did this by sharing the programs dir, notice line 143/144, the 'AdminConsole$' is my sharename).
- Create the Application Management Object.
- Create the Deployment Type Object.
- Create the Content Object.
- Add the Content Object and the Deployment Type Object to the Application Management Object.
- Create the application on the SCCM Server.
- Move the application to the correct folder, (if a folder was supplied, else it will exist in the root application directory).
_UPDATE_
Now invokes an implicit PSSession to the SCCM Server to get the ConfigurationManager ps module, so the share is no longer needed to get tto that.
running .New-SccmJavaApplication.ps1 :
I get error:
The term 'Invoke-JavaDownloadAndMsiExtraction' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
- .New-SccmJavaApplication.ps1
-
+ CategoryInfo : ObjectNotFound: (Invoke-JavaDownloadAndMsiExtraction:String) [.New-SccmJavaApplication.p s1], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException,.New-SccmJavaApplication.ps1
Suggestion [3,General]: The command Invoke-JavaDownloadAndMsiExtraction was not found, but does exist in the current
location. Windows PowerShell does not load commands from the current location by default. If you trust this command,
instead type: ".\Invoke-JavaDownloadAndMsiExtraction". See "get-help about_Command_Precedence" for more details.
After doing the change in New-SccmJavaApplication.ps1, I get:
ScriptHalted
At .... .New-SccmJavaApplication.ps1:38 char:5
-
throw $_
-
~~~~~~~~
- CategoryInfo : OperationStopped: (:) [], RuntimeException
- FullyQualifiedErrorId : ScriptHalted
Any Idea ?