-
-
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 | |
| } | |
| } |
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 ?
_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.