© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
O. HeaumeUnderstanding Microsoft Intunehttps://doi.org/10.1007/978-1-4842-8850-4_4

4. Detection Rules

Owen Heaume1  
(1)
West Sussex, UK
 

In Microsoft Intune, detection rules are used to determine the presence of a Win32 application. The detection rule will make sure that the application installation will only occur if it is not already installed and will also help to confirm a successful installation or not.

There are three types of detection rules built into Intune: MSI, file, and registry, and, for the most part, these will meet most of your needs. When they don’t, you will need to resort to using custom PowerShell detection rules.

This chapter will start by going over some detection fundamentals before moving on to how detection scripts work and the logic behind them. You will then learn about the various types of detection rules, with examples of each type ready to use with your own deployments. Finally, you will learn about custom rules and branching.

Why Use PowerShell?

As well as the three native detection rules, a fourth, more advanced detection type is available to use, and that is a custom detection script – this allows you to script a detection rule for practically anything, limited only by your imagination, and you achieve this by using PowerShell.

Using PowerShell can be a time saver as once you have a detection script saved that you know works, it’s a simple case of a small adjustment to two or three variables and uploading it to Intune – you can rest back on your chair, coffee in hand, knowing that the script has been tried-and-tested before and will do its job correctly.

This book is all for repeatable and reliable deployments, and PowerShell detection rules are a part of that process.

Detection Fundamentals

Let’s start by understanding what informs Microsoft Intune whether an application deployment has been successful or not.

The Microsoft Rules

Although the table in Figure 4-1 has been sourced from the Microsoft Configuration Manager documentation,1 it is still relevant for Intune, and it shows how you can use the output of a script to determine if an application has been installed.

A screenshot of a table with 5 columns and 8 rows. The column headers are script exit code, data from S T D O U T, S T D E R R, script result, and application detection.

Figure 4-1

Shows how the output of a script can signify a successful application install

Interpreting the Table

The part relevant to your scripted detection rule is the second column header: Data read from STDOUT.

STDOUT, or Standard Out, is a stream to which a program outputs its data. The way your detection script is going to use it is to output data to the screen by using a native PowerShell cmdlet.

Figure 4-2 (a cropped version of the table shown in Figure 4-1) shows it is the third row you are interested in: to signify a successful installation your script will need to write to the STDOUT data stream. In other words, if the data read from STDOUT is not empty (in other words, it has been written to), then the application detection state will be installed.

A screenshot of a table has 5 columns and 4 rows. Column headers are script exit code, data from S T D O U T, S T D E R R, result, and application detection. The third entry is highlighted.

Figure 4-2

If the data read from STDOUT is not empty then signify a successful app detection

In Practice

To achieve this, the PowerShell cmdlet Write-Host is used in the detection script code, and you will have seen this cmdlet from Chapter 1, where you were encouraged to read the help files and try out the cmdlets for yourself.

The PowerShell help files for Write-Host state: “Writes customized output to a host.” The host in this case is STDOUT. Sounds perfect.

Write-Host will display text to the screen, and if you need a refresher from Chapter 1, you use it like this:
Write-Host "Hello Reader, are you enjoying this book?"

To signify a successful deployment, you need to use Write-Host to send a message to the screen. But what message should you send? Well, anything! You could use: Write-Host "Success!" or: Write-Host "Installed" just as much as you could use: Write-Host "What a nice day! Are you enjoying it?" As long as you write something it will be interpreted as a successful detection by Intune.

Note

Even though Write-Host will output text to the screen, the end user will never see it when used in a detection script. It will, however, turn up in the IntuneManagementExtension.log found at C:ProgramDataMicrosoftIntuneManagementExtensionLogs.

Where Do I Put the Detection Rules Anyway?

If you are coming from Microsoft Endpoint Configuration Manager (previously known as System Centre Configuration Manager or SCCM for short), then you may wonder if you can copy and paste your rules into a dialog box somewhere within the Intune portal. Currently, in Intune, this is not possible. You must create the detection rule in PowerShell, save it somewhere on your computers as a .ps1 file and then within the Intune portal, browse to the script location and select it to upload.

When you create a new application within the Intune management portal and select the type to be a Windows app (Win32), detection rules are stage four of the creation process.
  1. 1.

    Select the drop-down list next to “Rules format” and choose “Use a custom detection script” from the available options.

     
  2. 2.

    Select the folder icon next to “Script file” which will then allow you to browse to and select your .ps1 detection rule that you will have previously created and saved.

     
Figure 4-3 highlights the correct areas you will need to modify to upload your detection scripts.

A screenshot of windows apps. The detection rules segment highlights the rules format that lists use a custom detection script.

Figure 4-3

Stage four of Win32 app creation. Uploading a custom detection script in the Intune portal

Silently Continue

When crafting your own detection rules, you will often need to use the parameter -ErrorAction tacked onto the end of the relevant cmdlet being used.

This parameter allows the suppression of non terminating errors, and you should assign it the value of SilentlyContinue. (-ErrorActionSilentlyContinue)

A non terminating error is not as serious as a terminating error as it will not stop the script from running. This is in stark contrast to a terminating error which will immediately halt script execution.

Note

A terminating error cannot be silenced with the -ErrorAction parameter and if you want to handle them you should use try/catch blocks instead. That way if there is a terminating error, the code within the try block is halted and execution skips to the catch block where you can handle the error.

A non terminating error would otherwise prevent your detection script from doing its job properly. For example, if you were trying to validate a registry key on a system where the key did not exist, a non terminating error would be produced and written to STDERR (have another look at the table previously shown in Figure 4-1), resulting in script failure and the application detection state of unknown.

By adding the -ErrorAction SilentlyContinue parameter, the non terminating error is suppressed should it occur, allowing the script to continue to exit normally and generate the correct failure exit code.

It is probably easier to demonstrate this so let’s try it out. In a PowerShell prompt, execute the following: Get-Item c: hisdoesnotexist

Assuming there is not a folder or file named thisdoesnotexist at that location, a non terminating error will be written to STDERR, and a red error message will be presented on screen because, well, it doesn’t exist. (See Figure 4-4)

A screenshot of windows powershell that executes the get item file name this does not exist.

Figure 4-4

The location doesn’t exist and a sea of red is produced

Now try this: Get-item c: hisdoesnotexist -Erroraction SilentlyContinue

Nada. Nothing. Zilch. Diddly Squat. Error suppressed. (See Figure 4-5)

A screenshot of windows powershell that executes the get item file name this does not exist. No result is recorded.

Figure 4-5

This time the error is suppressed and nothing is displayed on the screen

How Detection Scripts Work

The way a detection script works can be summarized in plain English as, “Check if this condition is true, if it is, then it means the application has successfully installed and we should use Write-Host to let Intune know that.”

To summarize it even more succinctly, “If this, then that.”

In PowerShell, you will use the IF statement to achieve the desired goal. The IF statement is followed by opening and closing brackets. Within the brackets is the condition that you wish to evaluate as being true. (Usually, this is the test condition that proves the application has been installed.) (See Listing 4-1.)
If <condition is true> then <Inform Intune installation was successful>
Listing 4-1

A simplified explanation of If…then

In PowerShell, the then; part of the statement is represented by the curly braces { } and anything in between the curly braces is what should be executed in the event of the condition evaluating to true; like informing Intune the application install was successful. (See Listing 4-2.)
If (Condition is true) {
      <Inform Intune installation was successful>
}
Listing 4-2

PowerShell If Statement construction – If this, then that

If the IF condition evaluates to false, meaning the application was not detected, then the code between the curly braces is skipped, Intune is not informed of a successful installation by using Write-Host to write to STDOUT, and the script executes successfully with nothing written to either STDOUT or STDERR.

Consulting the first row in the table shown previously in Figure 4-1, you can see that having nothing written to STDOUT or STDERR, as well as a successful script execution, will signify to Intune that the application was not installed.

Detection Rule Types

Now that the fundamentals have been covered, it is time to look at the common detection rule types used in application deployment.

Note

As teaching PowerShell is beyond the scope of this book, I will not explain the minutiae of the inner workings of each detection rule, although if you have read the preceding chapters then you will have some basic understanding already. As with anything, you learn best by doing, and you should read the PowerShell help files on anything that you feel requires clarification and try the code out for yourself on a test computer.

File/Folder Presence

One of the simpler detection methods is to verify the existence of a file or folder.

To use the code examples shown in Listing 4-3, do the following:
  • Set the $fileOrFolderName variable to the file or folder name to detect.

  • Set the variable $path to the location of the file or folder to detect.

(You can add or leave trailing backslashes when setting the path variable as Join-Path sorts this out for you.) Listing 4-3 detects the presence of the text file: All Servers.txt stored in C:ohtemp.

If the file is found, and therefore the condition has been evaluated to true, then Write-Host is invoked which outputs a message to the screen: “Detected!”
$fileOrFolderName = "All Servers.txt"
$path = "C:ohtemp"
If (Test-Path (Join-Path -Path $path -ChildPath ↩$fileOrFolderName)) {
    Write-Host "Detected!"
}
Listing 4-3

Detecting file existence

Testing for folder existence is achieved using the same method, specifying a folder name instead of a file name for the $fileOrFolderName variable.

Listing 4-4 demonstrates testing for the existence of a folder named, Important Folder located at C:ohtemp.
$fileOrFolderName = "Important Folder"
$path = "c:ohtemp"
If (Test-Path (Join-Path -Path $path -ChildPath ↩  $fileOrFolderName)) {
    Write-Host "Detected!"
}
Listing 4-4

Testing for folder existence

Executable Presence

Executable detection is identical code to file or folder detection, the only difference being the variable named $fileOrFolderName has been renamed to $Executable for clarity; particularly important if other people may eventually use your scripts.

In Listing 4-5, the code detects the presence of the Java executable, java.exe, found in the path C:ProgramFiles(x86)javajre1.8.0_333in

Note the use of the PowerShell environment variable: ${env:ProgramFiles(x86)} in the code.
$executable = "java.exe"
$path = "${env:ProgramFiles(x86)}javajre1.8.0_333in"
If (Test-Path (Join-Path -Path $path -ChildPath $executable)) ↩
{
    Write-Host "Detected!"
}
Listing 4-5

Detecting the Java executable

Executable Version

While the previous example of detecting the presence of a specific executable can be useful, often it is more helpful to detect the version number of the executable.

Continuing to use java.exe as the example executable, let us now make sure it is also the expected version number.

In this instance, the version number of the .exe is 80.3330.2 as shown by right-clicking the java.exe file and looking at the Details tab on the properties page. (See Figure 4-6)

A screenshot of a window titled the java dot e x e properties. It lists the details descriptions in a table. The product version 8.0.3330.2 is highlighted.

Figure 4-6

Discovering the version number of the Java executable

PowerShell can obtain this information using the cmdlet Get-Item, and Listing 4-6 demonstrates the detection rule for this process.
$versionNumber = '8.0.3330.2'
$executable = "java.exe"
$path = "${env:ProgramFiles(x86)}javajre1.8.0_333in"
If ((Get-item (Join-Path -Path $path -ChildPath $executable) ↩
-ErrorAction SilentlyContinue).VersionInfo.ProductVersion ↩
-eq $VersionNumber) { ↩
    Write-Host "Detected!"
}
Listing 4-6

Detecting the product version of an executable file

Note

You can also use the FileVersion property with Get-Item instead of ProductVersion depending on your needs. For example: (Get-item (Join-Path -Path $Path -ChildPath $Executable)).VersionInfo.FileVersion

Finding the Build Number
Sometimes you will want the complete build number to use in the detection rule. For example, the Firefox.exe properties page presents the following information:
  • File version: 103.0.2.8255

  • Product version: 103.0.2

Figure 4-7 shows the properties page of Firefox exe where you can view this information.

A snapshot of the firefox dot e x e properties. It lists the details descriptions in a table. The product version 103.0.2 is highlighted.

Figure 4-7

The file version and product version of Firefox.exe

If you use Get-Item to retrieve either the file version or product version of Firefox.exe, the only value returned is 103.0.2. (See Figure 4-8)

A screenshot of the administrator windows powershell. The file version 103.0.2 for firefox dot e x e is returned.

Figure 4-8

The value returned is 103.0.2 even though the file version is requested

If your detection rule requires confirming the full file version number of 103.0.2.8255, then you will need to use the rudely named property, FilePrivatePart to retrieve the build number separately from the file version number. (See Figure 4-9)
(Get-Item "C:Program FilesMozilla ↩ Firefoxfirefox.exe").VersionInfo.FilePrivatePart

A snapshot of the administrator windows powershell. The file name file private part is used to retrieve the build number.

Figure 4-9

Retrieving the build number from Firefox.exe

The resulting detection rule tests for both parts, the file version number and the build number, and expects both to be present to signify a successful installation. It does this by using -and to evaluate two conditions: one for the file version and one for the build number, and both conditions need to be true.

In English, it would read as, “If the file version equals 103.0.2 and the build number equals 8255 then write to STDOUT to signify a successful application detection.”

Listing 4-7 shows the resulting detection rule.
$versionNumber = '103.0.2'
$buildNumber = '8255'
$executable = "firefox.exe"
$path = "$Env:ProgramFilesMozilla Firefox"
If ((Get-item (Join-Path -Path $path -ChildPath $executable) -ErrorAction ↩ SilentlyContinue).VersionInfo.FileVersion -eq $versionNumber -and (Get-item ↩
(Join-Path -Path $path -ChildPath $executable) -ErrorAction ↩ SilentlyContinue).VersionInfo.FilePrivatePart -eq $buildNumber) {
    Write-Host "Detected!"
}
Listing 4-7

The detection rule checks for both the file version and the build number

Registry Subkey

It is rare to only wish to detect the presence of a registry subkey. For accuracy, you would want to detect a specific value/data pair.

Should you need to though, the detection rule would resemble this. (By now I’m sure I don’t need to tell you to adjust the variable $RegistrySubKey in the code to meet your needs.)

Figure 4-10 shows the Google Chrome registry subkey the detection rule in Listing 4-8 is testing for.

A screenshot of the Google chrome registry editor subkey. It lists 14 files and the chrome file is selected.

Figure 4-10

The registry location of the Chrome subkey

$registrySubKey = "HKLM:SOFTWAREGoogleChrome"
If (Test-Path $registrySubKey) {
    Write-Host "Detected!"
}
Listing 4-8

The detection rule for the Chrome registry subkey

Registry Value/Data Pair

Now, this is more like it. Often, when you are using the registry for detection rules, you will be trying to detect a specific value and its corresponding data to signify a successful deployment.

For this example, if you have deployed the application Git for Windows you may decide to use the registry as the detection rule.

You want to be certain that version 2.32.0.2 has been deployed and decide to detect its registry value CurrentVersion and its corresponding data. (See Figure 4-11)

A screenshot of the registry editor. The git for windows file opens to a table with 3 columns and 4 rows. The current version entry is highlighted.

Figure 4-11

Checking the registry for the value and data to use in the detection script

The detection script to achieve this is shown in Listing 4-9.
$registryKey = 'HKLM:SOFTWAREGitForWindows'
$value = 'CurrentVersion'
$data = '2.32.0.2'
if ((Get-ItemProperty -Path $registryKey | Select-Object ↩  $value -ExpandProperty $value -ErrorAction ↩
SilentlyContinue) -eq $data) {
    Write-Host "Detected!"
}
Listing 4-9

Detection script for a registry value and data pair

Why Don’t You Just Silently Continue?
Perhaps an easier method to obtain the desired registry value/data would be to use the less complex detection rule shown in Listing 4-10.
$registryKey = 'HKLM:SOFTWAREGitForWindows'
$value = 'CurrentVersion'
$data = '2.32.0.2'
if ((Get-ItemPropertyValue -Path $RegistryKey -Name ↩
$Value -ErrorAction SilentlyContinue) -eq $data) {
    Write-Host "Detected!"
}
Listing 4-10

An easier detection method to obtain registry value/data maybe, but prone to error

Sure, it will work, but remember earlier in this chapter when you were learning about -SilentlyContinue and the difference between non terminating and terminating errors? The cmdlet Get-ItemPropertyValue will produce a terminating error if the value it is looking for does not exist. (This may be the case in a failed deployment.)

If you recall, the -SilentlyContinue switch will not suppress terminating errors and data will be written to the STDERR stream, signifying an unknown outcome.

The trick here is to refactor the code and pipe the contents from Get-ItemProperty (which outputs terminating errors) to Select-Object (which outputs non terminating errors), and will therefore be our host for the -SilentlyContinue parameter.

EXERCISE

Try this for yourself: using the detection rule in Listing 4-10 (adjusting the variables to a valid registry value and data pair on your system), verify that the value is detected and “Detected!” is written to your screen.

Then edit the $value variable to something that does not exist and run the same code again. What do you get?

Even though the -silentlyContinue switch is used, it has not stopped the error because it is a terminating error that was produced.

Now try the same thing with the detection rule in Listing 4-9. This time, there is no error message as it has been successfully suppressed.

It is important to always test the code that you write and find out what will happen if what you are trying to detect is not there or contains invalid data. Make sure that it has the desired outcome.

While it may be quicker to use shortcuts and forgo testing your code, in the end, putting in the hard work and doing it properly will save you headaches in the future. And remember, code is reusable. Do it properly once and it’s done forever, ready to be reused time and time again.

Custom Detection

There may come a time when you can’t find anything to detect or don’t care too much and wish to signify the deployment was successful regardless of any true verification.

What you are saying in situations like this is, “I don’t want to, or cannot validate that the application was successfully installed but I want to tell Intune that the installation was okay anyway.”

In edge cases like these (and there should be few instances where you need to do this), you can create a file, or registry subkey with associated value/data to detect as part of your deployment script and then validate its existence in the detection rules to signify a successful deployment, knowing it will always be a successful deployment.

An easier method still is to detect a default file or folder as these are already always present on Windows systems.

The following example detects the existence of cmd.exe, and you will have seen these very same detection rules used before in this chapter, just not for nefarious purposes like now! (See Listing 4-11.)
$executable = "cmd.exe"
$path = "$env:SystemRootsystem32"
If (Test-Path (Join-Path -Path $path -ChildPath $executable)) {
    Write-Host "Detected!"
}
Listing 4-11

Detecting for cmd.exe – you know it will always be there

Detecting for the presence of a default Windows system file as demonstrated by Listing 4-11 is the easiest method to achieve a lazy detection rule. Alternatively, you could opt for detecting a default folder guaranteed to be in place instead, and Listing 4-12 does just that, using the System32 folder for the detection rule.
$fileOrFolderName = "System32"
$path = $env:windir
If (Test-Path (Join-Path -Path $path -ChildPath ↩ $fileOrFolderName)) {
      Write-Host "Detected!"
}
Listing 4-12

Detecting the presence of the WindowsSystem32 installation directory

Custom File Detection

You may prefer to create a file to detect as part of the application deployment. Then, once the application has been installed the detection rule looks for the presence of the file just created, which, in turn, signifies a successful application detection.

One advantage of this method over detecting a default file or folder shown previously is that you can rename the created file on each updated deployment of the same application. For example, the first deployment of app1.exe creates an empty text file named App1-001.txt. If App1.exe is then updated and needs to redeploy, this time around the deployment creates and detects App1-002.txt.

As alluded to earlier, the text file is created in the same PowerShell script that deploys the application, and you should do this in the pre- or post-application install phase. It does not matter if you create the file before or after the application is installed because (and let’s face the ugly truth here), if you are using this method of application detection then you are either unable to detect the application through conventional means, or, and I hope this is not the case, you just don’t care.

When using this bad practice of detection, a good practice to follow is to create the custom files in a specific folder at a specific location, and out of reach of standard users.

You should write to the Windows directory, in a subdirectory named after the company you work for, followed by a directory called: Custom Detection. This fulfills two tasks: users are unable to delete its contents, (it is assumed that users log in with standard user permissions – if not you should ask yourself, “Why?”), and the directory then becomes the central storage area for any future projects you may end up working on where you need a repository for custom output or storage.

Here is an imaginary scenario to hammer home this concept.

Scenario: Yum-Yum Dog Foods Inc

Your manager approaches you with the following task: a new application, MyApp.exe, needs to be deployed to all staff.

You install the application on your test system and work out the installation command line.

You discover that once installed, there is no easy method of detecting the installation; having scoured the registry and file system you cannot find anything relevant to use as a detection rule.

You decide to use custom file detection and will create a file called: MyApp-001.log as part of the application deployment script and this can then be used in the detection rule you will write. You also add code to create the directory structure if it’s not present; if the structure is already present it will just create the file to detect.

To use this code, replace the values for the variables: $companyName and $fileName where Yum Yum Dog Foods Inc is the name of the company you work for and MyApp-001.log is the name of the file to be created.

Listing 4-13 shows the PowerShell code used in the application deployment script to create the custom file.
$companyName = 'Yum Yum Dog Foods Inc'
$fileName = 'MyApp-001.log'
$detectionPath = Join-Path -Path "$env:SystemRoot" ↩
-ChildPath "$CompanyNameCustom Detection"
if (!(Test-Path $DetectionPath)) {
      New-Item -Path $DetectionPath -ItemType Directory | ↩
Out-Null
}
New-Item -Path $DetectionPath -Name $FileName -ItemType ↩
File -Force | Out-Null
Listing 4-13

PowerShell code for writing a custom file to be used by the detection script

Figure 4-12 shows the resulting file, MyApp-001.log, ready for detection. The file structure Yum Yum Dog Foods IncCustom Detection is created if it did not already exist, otherwise, just the file MyApp-001.log is created.

A snapshot of the custom detection file. The myapp-001 dot log file is located in this P C, O S disk, windows, Yum yum dog foods section.

Figure 4-12

Successful creation of the custom detection file

You decide to use the code shown in Listing 4-14 to use as the detection rule.
$fileOrFolderName = "MyApp-001.log"
$path = "$env:SystemRootYum Yum Dog Foods Inc ↩
Custom Detection"
If (Test-Path (Join-Path -Path $path -ChildPath ↩ $fileOrFolderName)) {
    Write-Host "Detected!"
}
Listing 4-14

The detection rule used for MyApp-001.log

Custom Registry Detection

You may prefer to write to the registry instead of the file system for your custom detection and, much like creating custom files, and for the same reasons, it’s best to write to the registry in an organized structure; this keeps everything neat.

Continuing the previous scenario of working for Yum Yum Dog Foods Inc, here is where you could write in the registry:
HKEY_LOCAL_MACHINESOFTWAREYum Yum Dog Foods ↩ IncCustomDetection

Once again, the PowerShell code in Listing 4-15 will first check to see if this location exists in the registry already, and if not, create it before finally writing the value and data to be used for detection.

To use this code, replace the values for the variables, $companyName with the name of the company you work for, $applicationName with the name of the application you are deploying, and $value with the value you will detect in the detection rule: This can be anything, although, for simplicity, it’s best to stick with sequential numbers starting from 0 or 1.
$companyName = 'Yum Yum Dog Foods Inc'
$name = 'MyApp'
$value = '1'
$registryPath = Join-Path -Path "HKLM:SOFTWARE" ↩
-ChildPath "$companyNameCustom Detection"
if (!(Test-Path $registryPath)) {
    New-Item -Path $registryPath -Force | Out-Null
}
New-ItemProperty -Path $registryPath -Name $name ↩
-Value $value -PropertyType DWORD -Force | Out-Null
Listing 4-15

PowerShell code for writing a custom registry entry to be used by the detection script

Figure 4-13 shows the resulting registry value and data pair ready for the custom detection rule.

A screenshot of the registry editor. The location of the custom detection section and myapp entry on the right is highlighted.

Figure 4-13

Successful creation of the custom detection registry entry

The detection rule that matches up with this is shown in Listing 4-16.
$registryKey = 'HKLM:SOFTWAREYum Yum Dog Foods ↩
IncCustom Detection'
$value = 'MyApp'
$data = '1'
if ((Get-ItemProperty -Path $registryKey | Select- ↩
Object $value -ExpandProperty $value -ErrorAction ↩ SilentlyContinue) -eq $data) {
    Write-Host "Detected!"
}
Listing 4-16

The rule to detect the custom registry data

Final Thoughts on Custom Detection

Don’t use it! Joking aside, there may come a time when this is the only method available to you and it is good to have this knowledge in your toolbelt, just in case.

Remember though, creating items for custom rules to detect is not good practice and won’t verify the deployed application is installed. They should only be used as a last resort. They do, however, get you out of a bind in times of need.

Branching

Sometimes you will want to detect either in one location or another depending on if a 32-bit or 64-bit installation has occurred.

A single deployment script can be configured to install either a 32-bit or 64-bit program depending on the target computer “bitness,” and you may not know ahead of time if the detection rule needs to query inside of Program Files (x86) or Program Files.

Although not so common now, you may also wish to detect based on Microsoft Office bitness (e.g. a 32-bit Microsoft Office installation or a 64-bit Microsoft Office installation).

Solve these scenarios by using branching detection rules.

By Office Bitness

In this example detection rule, querying the installed Microsoft Office “bitness” will cause code execution to branch to the correct detection rule to use, based on if the query result is either 32-bit or 64-bit.

In English, the code reads something like this: “If the installed Office version is x86 (32-bit) then use this detection rule. If the Office version is x64 (64-bit) then use this other detection rule.”

Edit each of the two if statements in the code sample shown in Listing 4-17 to detect whatever you need to signify a successful installation based on the installed Office “bitness.”
$OfficePath = 'HKLM:SoftwareMicrosoftOffice'
$OfficeVersions = @('14.0','15.0','16.0')
foreach ($Version in $OfficeVersions) {
    try {
          Set-Location "$OfficePath$VersionOutlook" ↩
 -ea stop -ev x
          $LocationSet = $true
          break
      } catch {
          $LocationSet = $false
      }
}
if ($locationSet) {
      switch (Get-ItemPropertyValue -Name "Bitness") {
      "x86" { if ( <# Detect something here – ↩
file existence, file version etc #> ) { Write-host ↩ "Installed!"}}
      "x64" { if ( <# Detect something here – ↩
 file existence, file version etc #> ) { Write-host ↩ "Installed!"}}
      }
}
Listing 4-17

A detection rule based on Microsoft Office “bitness”

Note

Listing 4-17 will not run “as-is” as the two IF statements are missing conditions. Once you add the conditions to test for, the code will execute as expected. This is demonstrated in the next scenario.

Scenario – Detecting Mimecast

Mimecast is an application that has two installers: one 32-bit installer and one 64-bit installer. If the client computer has a 32-bit version of Microsoft Office installed, then the 32-bit version of Mimecast must be installed. Likewise, if the client computer has a 64-bit version of Microsoft Office installed then the 64-bit version of Mimecast needs to be installed.

In this scenario, the correct version of Mimecast has been installed and now a detection rule needs to be created that will detect successful installation by querying the correct installed location, either Program Files (x86) or Program Files.

The detection rule queries the “bitness” of the installed Microsoft Office version to determine which path (Program Files (x86) or Program Files) to check the file version of muspkg32.exe and ensure that it matches 7.6.0.11151, if it does, Write-Host is used to signify a successful installation. Listing 4-18 demonstrates this scenario.
$MimecastVersion = '7.6.0.11151'
$OfficePath = 'HKLM:SoftwareMicrosoftOffice'
$OfficeVersions = @('14.0','15.0','16.0')
foreach ($Version in $OfficeVersions) {
    try {
        Set-Location "$OfficePath$VersionOutlook" ↩
-ea stop -ev x
        $LocationSet = $true
        break
    } catch {
        $LocationSet = $false
    }
}
if ($locationSet) {
    #Check for bitness then check correct file version
    switch (Get-ItemPropertyValue -Name "Bitness") {
        "x86" { if ((get-item ↩ "${env:ProgramFiles(x86)}MimecastMimecast ↩
Outlook Add-Inmusepkg32.exe" -ErrorAction ↩ SilentlyContinue).VersionInfo.fileversion -eq ↩ $MimecastVersion) { Write-host "Installed!"} }
        "x64" { if ((get-item ↩ "$ENV:ProgramFilesMimecastMimecast ↩
Outlook Add-Inmusepkg32.exe" -ErrorAction ↩ SilentlyContinue).VersionInfo.fileversion -eq ↩ $MimecastVersion) { Write-host "Installed!"}}
    }
}
Listing 4-18

Detecting Mimecast based on the “bitness” of Microsoft Office

Or What?

I wanted to demonstrate how you could use Office bitness in a detection rule for completeness; however, it’s a bit of an overkill and complicated to read. Instead, using PowerShell’s logical operator -or could be a better alternative and you may find this more suitable for future detection scripts that require branching of some kind.

It reads as this: “If you have detected the correct executable version in Program Files (x86) OR if you have detected the correct executable version in Program Files, then inform Intune that installation was successfully detected.”

By using -or, it doesn’t matter which path the executable file was found in that you are using for detecting the version number against – so long as it was found in one of the correct paths then it is a success.

Listing 4-19 demonstrates this using -or to detect if musepkg32.exe was installed in either Program Files (x86) or Program Files.
$programFiles32 = (get-item ↩ "${env:ProgramFiles(x86)}MimecastMimecast ↩
 Outlook Add-Inmusepkg32.exe" -ErrorAction ↩ SilentlyContinue).VersionInfo.FileVersion
$programFiles64 = (get-item ↩ "$ENV:ProgramFilesMimecastMimecast ↩
Outlook Add-Inmusepkg32.exe" -ErrorAction ↩ SilentlyContinue).VersionInfo.FileVersion
if ($programFiles64 -eq '19.0.0.60' -or $programFiles32 ↩
-eq '10.0.19041.1') {
    Write-Host "Installed!"
}
Listing 4-19

Using PowerShell -or operator in the Mimecast detection rule

This and This

In this last example, both versions of Java (32-bit and 64-bit) were deployed, and therefore for the deployment to be considered successful both versions of Java must be detected.

To do this, the detection queries the version number of Java.exe in both Program Files (x86) and Program Files to ensure they match the required value for the detection rule to signify success. Listing 4-20 demonstrates how this is achieved using the -and operator.
$VersionNumber = '8.0.3410.10'
$Executable = "java.exe"
$32BitPath = "${env:ProgramFiles(x86)}Javajre1.8.0_341in"
$64BitPath = "$env:ProgramFilesJavajre1.8.0_341in"
If ((Get-item (Join-Path -Path $32BitPath -ChildPath $Executable) -ErrorAction ↩ SilentlyContinue).VersionInfo.ProductVersion -eq ↩ $VersionNumber -and (Get-item (Join-Path -Path ↩
$64BitPath -ChildPath $Executable) -ErrorAction ↩  SilentlyContinue).VersionInfo.ProductVersion -eq ↩ $VersionNumber) {
    write-host "Installed!"
}
Listing 4-20

Detecting this and this to signify a successful detection

Tip

Both -or and -and are known as logical operators. To find out more information on these and other logical operators, try using the built-in help by typing the following in a PowerShell console: help About_Logical_Operators

Summary

Well, who knew there would be so much to learn about detection rules? This has been a long chapter and you have covered a lot of ground.

First, you learned about why you might use PowerShell for your detection rules, before moving on to some fundamentals. You learned how to deal with terminating and non terminating errors and how detection scripts work. There are a lot of different types of detection rules and by now you should be able to identify which detection rule will meet your needs. For those edge cases, you learned how to use custom detection rules which can get you out of a bind in times of need. Finally, you learned about detection rule branching.

In the next chapter, you will learn about more advanced application deployment scenarios involving additional file copy operations and where to place the files for deployment. The chapter also covers how to reference the files within the PowerShell deployment script.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.78.30