If you are ever in need of deploying a plugin to “IntelliJ IDEA Ultimate”, “IntelliJ IDEA Community Edition” or “JetBrains Rider” using Intune, I have done the groundwork for you already. PSADT is not a good option here as the Plugins has to be installed in the users context (and PSADT requires elevation).
The solution I came up with consist of a Win32 application that will try to automatically install the Plugin for any version of IntelliJ and Rider that is found on the targeted computers, as they are using the same Plugin type. The Plugin application can be deployed to all devices, but will only install on devices that has IntelliJ and/or Rider installed. Another requirement for the installation to function correctly is that IntelliJ and/or Rider has to have been launched atleast once on the computer (The version specific plugin folder in %AppData% has to exist). If the deployment is setup as descibed in this guide, the plugin will also be installed if an additional required product gets installed at a later point in time.
In this example we will deploy a plugin called “IntelliJPlugin-1.0.0.jar”. Note! It is important that you have the version number as part of the name of the .Jar file. If not, you will have to find a way to read the version number from within the .jar container.
The solution consists of 4 PowerShell scripts + the Plugin .jar file ofc. The PowerShell scrips are the following:
- Install.ps1
- Uninstall.ps1
- Detection.ps1
- Requirement.ps1
Lets start with the Install.ps1 script which will find out what IntelliJ product(s) are installed and installe the Plugin into the plugin directoy/directories (Note that a transcript will be placed in the users %TEMP% folder for troubleshooting purposes):
Start-Transcript -Path "$env:TEMP\IntelliJPlugin.log" -Append
# Define plugin file name and location
$CurrentDirectory = get-location
$pluginFileName = "IntelliJPlugin-1.0.0.jar"
$pluginFilePath = "$CurrentDirectory\$pluginFileName"
# Software names and their corresponding plugin folders
$softwareNames = @{
"IntelliJ IDEA" = "IntelliJIdea*";
"IntelliJ IDEA Community Edition" = "IdeaIC*";
"Rider" = "Rider*";
}
# Get all installed software from the registry
$installedSoftware = Get-ChildItem -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" |
ForEach-Object { Get-ItemProperty $_.PSPath } |
Select-Object -Property DisplayName
foreach ($software in $softwareNames.Keys) {
# Check if the software is installed
$isInstalled = $installedSoftware.DisplayName | Where-Object { $_ -match $software }
if ($null -eq $isInstalled) {
Write-Output "$software is not installed."
continue
}
Write-Output "$software is installed."
# Get all directories in the JetBrains APPDATA folder
$jetBrainsDirs = Get-ChildItem -Path "$env:APPDATA\JetBrains" -Directory -Recurse -ErrorAction SilentlyContinue
# Filter directories that match the software name
$pluginFolderFilter = $softwareNames[$software]
$softwareFolders = $jetBrainsDirs | Where-Object { $_.Name -like $pluginFolderFilter }
if ($softwareFolders -eq $null) {
Write-Output "Could not find $software folder."
continue
}
foreach ($softwareFolder in $softwareFolders) {
# Check if plugins folder exists, create if not
$pluginFolderPath = Join-Path -Path $softwareFolder.FullName -ChildPath "plugins"
if (!(Test-Path -Path $pluginFolderPath)) {
New-Item -ItemType Directory -Path $pluginFolderPath | Out-Null
Write-Output "Created plugins folder at $pluginFolderPath for $software"
}
# Copy the plugin file to the plugins directory only if it does not exist
$destinationPath = Join-Path -Path $pluginFolderPath -ChildPath $pluginFileName
if (!(Test-Path -Path $destinationPath)) {
try {
Copy-Item -Path $pluginFilePath -Destination $destinationPath -ErrorAction Stop
Write-Output "$pluginFileName was copied successfully to $destinationPath for $software"
} catch {
Write-Output "Error occurred while copying $pluginFileName for $software : $_"
}
} else {
Write-Output "$pluginFileName already exists at $destinationPath for $software"
}
}
}
Stop-Transcript
The Uninstall.ps1 script will make sure that the plugin is removed from the device (Note that a transcript will be placed in the users %TEMP% folder for troubleshooting purposes).
Start-Transcript -Path "$env:TEMP\IntelliJPlugin.log" -Append
# Define plugin file name
$pluginFileName = "IntelliJPlugin-1.0.0.jar"
# Software names and their corresponding plugin folders
$softwareNames = @{
"IntelliJ IDEA" = "IntelliJIdea*";
"IntelliJ IDEA Community Edition" = "IdeaIC*";
"Rider" = "Rider*";
}
# Get all directories in the JetBrains APPDATA folder
$jetBrainsDirs = Get-ChildItem -Path "$env:APPDATA\JetBrains" -Directory -Recurse -ErrorAction SilentlyContinue
foreach ($software in $softwareNames.Keys) {
# Filter directories that match the software name
$pluginFolderFilter = $softwareNames[$software]
$softwareFolders = $jetBrainsDirs | Where-Object { $_.Name -like $pluginFolderFilter }
foreach ($softwareFolder in $softwareFolders) {
# Check if plugins folder exists
$pluginFolderPath = Join-Path -Path $softwareFolder.FullName -ChildPath "plugins"
if (Test-Path -Path $pluginFolderPath) {
# Check if the plugin file is in the plugins directory
$pluginFilePath = Join-Path -Path $pluginFolderPath -ChildPath $pluginFileName
if (Test-Path -Path $pluginFilePath) {
try {
Remove-Item -Path $pluginFilePath -ErrorAction Stop
Write-Output "$pluginFileName was removed successfully from $pluginFilePath for $software"
} catch {
Write-Output "Error occurred while removing $pluginFileName for $software : $_"
}
}
}
}
}
Stop-Transcript
Exit 0
Then we have the Detection.ps1 script used for detecting if the Plugin is installed or not.
# Define plugin file name
$pluginFileName = "IntelliJPlugin-1.0.0.jar"
# Software names and their corresponding plugin folders and registry keys
$softwareNames = @{
"IntelliJ IDEA" = @{Folder="IntelliJIdea*"; Key="IntelliJ IDEA [0-9]*"};
"IntelliJ IDEA Community Edition" = @{Folder="IdeaIC*"; Key="IntelliJ IDEA Community Edition*"};
"Rider" = @{Folder="Rider*"; Key="JetBrains Rider*"};
}
# Get all directories in the JetBrains APPDATA folder
$jetBrainsDirs = Get-ChildItem -Path "$env:APPDATA\JetBrains" -Directory -ErrorAction SilentlyContinue
$allPluginsInstalled = $true
$softwareDetected = $false
# Get all installed programs from the registry
$installedPrograms = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue
foreach ($software in $softwareNames.Keys) {
# Check if the software is installed
$softwareRegistryKey = $softwareNames[$software].Key
if ($installedPrograms.DisplayName -like $softwareRegistryKey) {
$softwareDetected = $true
# Filter directories that match the software name
$pluginFolderFilter = $softwareNames[$software].Folder
$softwareFolders = $jetBrainsDirs | Where-Object { $_.Name -like $pluginFolderFilter }
foreach ($softwareFolder in $softwareFolders) {
# Check if plugins folder exists
$pluginFolderPath = Join-Path -Path $softwareFolder.FullName -ChildPath "plugins"
if (Test-Path -Path $pluginFolderPath) {
# Check if the plugin file is in the plugins directory
$pluginFilePath = Join-Path -Path $pluginFolderPath -ChildPath $pluginFileName
if (!(Test-Path -Path $pluginFilePath)) {
$allPluginsInstalled = $false
break
}
} else {
$allPluginsInstalled = $false
break
}
}
if (!$allPluginsInstalled) {
break
}
}
}
if ($allPluginsInstalled -and $softwareDetected) {
write-host "Everything is fine!"
} else {
}
Last but not least, we have our Requirement.ps1 script. The script checks for the existance of IntelliJ & Rider installed from either the native installers from JetBrains website or through “JetBrains Toolbox” installer and checks if the application has been launched atleast once:
# Software names and their corresponding registry keys
$softwareNames = @{
"IntelliJ IDEA" = "IntelliJ IDEA [0-9]*";
"JetBrains Toolbox IntelliJ IDEA" = "IntelliJ IDEA Ultimate";
"IntelliJ IDEA Community Edition" = "IntelliJ IDEA Community Edition [0-9]*";
"JetBrains Toolbox IntelliJ IDEA Community Edition" = "IntelliJ IDEA Community Edition";
"Rider" = "JetBrains Rider*";
"JetBrains Toolbox Rider" = "Rider";
}
# Get all installed programs from the registry
$installedPrograms = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue
# Get all installed programs from the HKEY_CURRENT_USER registry (JetBrains Toolbox Installer)
$installedProgramsUser = Get-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' -ErrorAction SilentlyContinue
# Variable to hold the names of installed software
$installedSoftware = @()
foreach ($software in $softwareNames.Keys) {
# Check if the software is installed
$softwareRegistryKey = $softwareNames[$software]
if (($installedPrograms.DisplayName -like $softwareRegistryKey) -or ($installedProgramsUser.DisplayName -like $softwareRegistryKey)) {
$installedSoftware += $software
}
}
if ($installedSoftware.Count -gt 0) {
foreach ($software in $installedSoftware) {
Write-Host "$software is installed"
}
} else {
Write-Host "Nope!"
}
Now to wrap the Installation files into a .Intunewin file using https://github.com/microsoft/Microsoft-Win32-Content-Prep-Tool. The Installation files are:
- Install.ps1
- Uninstall.ps1
- IntelliJPlugin-1.0.0.jar
Create a Win32 application and Import the .Intunewin file.
Set the Install and Uninstall command as follows:
Setup the requirement rule as follows, and make sure to select your “Requirement.ps1” script as below:
Now for the Detection rule, make sure to select your newly created “Detection.ps1” script:
Now you just need to deploy it as required to the devices you wish to deploy it to. To make the installation more visual for users, I would recommend to also make it available for users. This will make the application visible in the Company Portal and users can see if they do not have the requirements in place.
After some time, the report/overview should be showing you the result of your deployment.
Note that the “Not Applicable”, shows the devices that do not have the requirements fulfilled (i.e IntelliJ and/or Rider Installed + having the app started up the first time).
One thought on “Intune: Deploy a IntelliJ and Rider plugin via a Win32 Application.”