© 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_7

7. Deploying the Script

Owen Heaume1  
(1)
West Sussex, UK
 

Once you have a PowerShell script or deployment template ready to go, you will need to understand the command line required to deploy it in Intune.

This is the moment you have been building up to, pacing up and down like an expectant father. Like Doctor Frankenstein’s monster, it is time to give this thing life: it is time to deploy it using the Intune Management Portal, Win32 App creation.

In this chapter, you will learn how to construct the correct install commands that are input into the Intune Portal when creating a new Win32 application deployment.

Sys What Now?

The Intune Management Extension is a 32-bit application that executes PowerShell scripts or processes Win32 applications.

In most cases, whenever a 32-bit application attempts to access %windir%System32 or %windir% egedit.exe, the access is redirected to an architecture-specific path, for example, %windir%SysWOW64, where 32-bit versions of the file being accessed are used instead.

The management extension executes in the 32-bit context resulting in the deployed PowerShell script also executing in the 32-bit version of PowerShell running from SysWOW64.

This may not have the outcome you desire and could cause deployment failure, as some cmdlets require running in a 64-bit context. Other unexpected results may occur too: the cmdlet Get-Process, for example, will only get 64-bit processes in 64-bit PowerShell and 32-bit processes in 32-bit PowerShell which may or may not be what you are expecting. In general, you will always want your PowerShell script to run in the 64-bit version of PowerShell.exe

To avoid this situation, there is another folder, called Sysnative, and it can be used as a replacement for System32 in the path name.

Sysnative as a special alias is used to indicate that the file system should not redirect the access. When you specify C:WindowsSysnative in your code or application, it is diverted to C:WindowsSystem32 instead.

Solution

To ensure the PowerShell script executes using the 64-bit version of PowerShell, a small modification must be made to the “Install Command” and/or “Uninstall Command” fields in the Intune portal. You must reference the full path of the 64-bit version of PowerShell.exe using Sysnative in place of System32.

32-Bit PowerShell

If you deliberately wish to use the 32-bit version of PowerShell, then you can reference the executable from:
C:Windowssyswow64WindowsPowerShellv1.0powershell.exe
Tip

In the Intune portal “Install command” field, you can reference powershell.exe directly, omitting the full path. This is because the Intune Management Extension will be running in a 32-bit process and will therefore call PowerShell.exe from a 32-bit process by default.

Note the 32-bit version is in the SysWOW64 directory. You can prove this PowerShell version is 32-bit by typing C:Windowssyswow64WindowsPowerShellv1.0powershell.exe in the Run dialog box to launch the PowerShell console, and then typing [System.Environment]::Is64BitProcess. The output will be False, in answer to the question, “Is this a 64-bit process?” (See Figure 7-1.)

A screenshot of a window titled windows powershell. It has a code to run a 32-bit version of powershell.

Figure 7-1

Running 32-bit PowerShell from SysWOW64 directory

64-Bit PowerShell

When creating the command line to use from within the Intune portal, you must reference 64-bit PowerShell.exe using the full path and substitute System32 with Sysnative:
"C:WindowsSystem32WindowsPowerShellv1.0PowerShell.exe"
is replaced by
"C:WindowsSysnativeWindowsPowerShellv1.0PowerShell.exe"

Calling Your Script

Once you have a PowerShell deployment script, you will need to ask yourself the following questions about it:
  • Is it just a script that executes sequentially from top to bottom?

  • Does it have an entry point?

  • Does it have an entry point with parameters?

  • Is it a function?

  • Does the function accept parameters?

The script type determines which command line is used within the Windows Win32 App creation in the Intune Portal.

Standard Script (Top to Bottom)

This type of script is executed from top to bottom. Listing 7-1 shows an example of this script type.
# This is an example of a standard script.
# It is executed sequentially from top to bottom.
[int]$ValueA = 10
[int]$ValueB = 20
[Int]$Total = $ValueA + $ValueB
Write-Output "I have just done some incredible things ↩
with this script!"
Write-Output "Including adding up two values! ↩
The answer is: $Total"
Listing 7-1

A script that executes from top to bottom

Install Command

Listing 7-2 shows the install command to use for a standard script.
"C:WindowsSysnativeWindowsPowerShellv1.0↩
PowerShell.exe" -noprofile -executionpolicy ↩
bypass -file .myScript.ps1
Listing 7-2

The install command for a standard script. (Top to Bottom)

Script with Entry Point

Like the Standard Script (Top to Bottom), the same command line is used.

This type of script allows for more flexibility as the entire code is encapsulated as a function. The very last line of code that is then outside of that function will call the function itself which may or may not accept parameters too.

Script with Entry Point (No Parameters)

Listing 7-3 shows an example of a script with an entry point. The script is executed top to bottom and the entry point within the script itself calls the function to do the clever stuff.
Function Invoke-ApplicationInstall {
    # This function does some clever deployment stuff here
}
# The next line (line 6) is the script entry point:
Invoke-ApplicationInstall
Listing 7-3

A script containing an entry point and not using any parameters

Install Command
Listing 7-4 shows the full command line to use with this type of script.
"C:WindowsSysnativeWindowsPowerShellv1.0PowerShell.exe" ↩
-noprofile -executionpolicy bypass -file .myScript.ps1
Listing 7-4

The command line for a script with an entry point. (No Parameters used)

Script with Entry Point (With Parameters)

Deploying a script with an entry point which calls a function with parameters is the same as without parameters. The exception is the entry point calling the function includes the desired parameters. Listing 7-5 demonstrates this.
Function Invoke-ApplicationInstall {
      [CmdletBinding()]
      Param (
      [Parameter(Mandatory=$true)]
      [ValidateSet("x64","x86")]
      [String]$Architecture,
      [Parameter(Mandatory=$true)]
      [ValidateNotNullorEmpty()]
      [String]$Text
      )
 # This function does some clever deployment here...
}
# Script entry point with parameters of -Architecture ↩
and -Text:
Invoke-ApplicationInstall -Architecture x64 ↩
-Text "Some important text"
Listing 7-5

A script with an entry point containing parameters

Install Command
Listing 7-6 shows the full command line to use with this type of script.
"C:WindowsSysnativeWindowsPowerShellv1.0PowerShell.exe" ↩
-noprofile -executionpolicy bypass -file .myScript.ps1
Listing 7-6

The command line for a script with an entry point using parameters

Function

To directly reference a function in a script, a slightly different method must be used. To create the installation command line for scripts that include a specific function you wish to execute, you will use something called dot sourcing.

Normally, a script runs in the script scope meaning you do not have direct access to the functions, variables, etc., that it contains.

Dot sourcing allows you to run the script in the current scope, and all the commands in the script are available as if you had typed them at the command prompt.

To use dot sourcing, place a . (period) and a space before the script path.

For example:
. C:myScriptsmyScript.ps1
or
. .myScript.ps1

You can read all about dot sourcing by typing in help about_scripts in a PowerShell console.

Note

You will notice that the command line for functions includes an & sign (ampersand). This is known as a call operator, and you can use it to execute scripts using their filenames. You can find out more about operators by reading the built-in help: help about_operators.

Function (No Parameters)

Let us say you have written a super-duper function called, Do-Something, and it is contained in a script named, Function.ps1. Listing 7-7 demonstrates what the function may look like.
function Do-Something {
 [CmdletBinding()]
 param ()
    Process {
        write-output "I'm doing something really cool"
    }
}
Listing 7-7

A function containing no parameters. The script is saved as “Function.ps1”

Install Command

In this example, the script has been saved as “Function.ps1” and the name of the function to run is named “Do-Something.”

Listing 7-8 demonstrates the installation command line to use.
"C:WindowsSysnativeWindowsPowerShellv1.0PowerShell.exe" ↩
-noprofile -executionpolicy bypass -command "& ↩ { . .function.ps1; Do-Something}"
Listing 7-8

A sample function that does not contain parameters. The function has been saved as “Function.ps1”

Function Accepting Parameters

Like deploying a function without parameters, the command line used is the same, except you add the required parameters and respective values.

For this example, let us pretend you have a script named, myScript.ps1 and within this script, there is a function named, Show-Text. The function accepts a single parameter named, $textToDisplay. Based on the supplied parameter, the function then goes on to do something spectacularly amazing when executed.

Listing 7-9 demonstrates the function for this.
function Show-Text {
    [CmdletBinding()]
      param (
      [parameter (Mandatory=$true)]
      [string]$textToDisplay
      )
      Process {
          write-output "I'm doing something really cool ↩
using the supplied parameter of: $textToDisplay"
      }
}
Listing 7-9

A function that accepts parameters

Install Command
The goal here is to
  • Call the script named, myScript.ps1
    • Specifically execute within the script the function named Show-Text.

  • Supply the function parameter -textToDisplay with the value of “Important Text!”

Listing 7-10 demonstrates the command line to achieve this.
"C:WindowsSysnativeWindowsPowerShellv1.0PowerShell.exe" ↩
-noprofile -executionpolicy bypass -command "& ↩ { . .myScript.ps1; Show-Text -textToDisplay "Important ↩ Text!" }"
Listing 7-10

The command line used to call a function using parameters

Example: Deploying a Script Containing Two Functions

There may come a time when you have a single script containing multiple related functions. For example, your script may include one function for installation and another function for uninstallation.

As Intune allows you to specify two command lines, one for installation and one for uninstallation, then this is a good reason to use two public functions in a single script.

Note

This example does not walk you through the complete creation of the application, as you will learn this later in the book. Rather, it demonstrates the deployment of a complex script, that is only a script (no additional files are deployed to the endpoint), with the script containing two functions; each of which can be used independently within the same Intune application creation.

Remote Server Administration Tools

This example script deploys the RSAT1 (Remote Server Administration Tools) capabilities for Windows 10 and contains the code to uninstall it too if required. It is achieved using two functions in a single script saved as “ManageRSAT.ps1”.

The two functions are
  • Install-RSATCapabilities

  • Uninstall-RSATCapabilities

Listing 7-11 displays the full contents of the script.
function Install-RSATCapabilities {
    [CmdletBinding()]
    param()
    BEGIN {
        $Components = @('Rsat.Dns.Tools~~~~0.0.1.0',↩
'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0',↩
'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0',                        'Rsat.DHCP.Tools~~~~0.0.1.0',↩
'Rsat.FileServices.Tools~~~~0.0.1.0','Rsat.IPAM.Client.Tools~~~~0.0.1.0', ↩                       'Rsat.VolumeActivation.Tools~~~~0.0.1.0','Rsat.↩
CertificateServices.Tools~~~~0.0.1.0','Rsat.BitLocker.↩
Recovery.Tools~~~~0.0.1.0')
        $val = Get-ItemProperty -Path ↩ "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdate↩
AU" -Name "UseWUServer" | select -ExpandProperty ↩
UseWUServer -ErrorAction SilentlyContinue
        Set-ItemProperty -Path ↩ "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdate↩
AU" -Name "UseWUServer" -Value 0 -ErrorAction ↩ SilentlyContinue
        Restart-Service wuauserv -ErrorAction SilentlyContinue
    }
    PROCESS {
        foreach ($Component in $Components) {
            $InstallState = (Get-WindowsCapability ↩
-Name $Component -Online -ErrorAction SilentlyContinue)↩
.state
            if ($InstallState -eq "NotPresent") {
                Write-Verbose "Adding: $Component..."
                Add-WindowsCapability -Online -Name ↩
$Component -ErrorAction SilentlyContinue
            } else {
                write-verbose "$Component already present."
            }
        }
    }
    END {
        Set-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdate↩
AU" -Name "UseWUServer" -Value $val -ErrorAction ↩ SilentlyContinue
        Restart-Service wuauserv -ErrorAction SilentlyContinue
    }
}
function Uninstall-RSATCapabilities {
    [CmdletBinding()]
    param()
    BEGIN {
        $Components = @('Rsat.Dns.Tools~~~~0.0.1.0',↩
'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0',↩
'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0', ↩                        'Rsat.DHCP.Tools~~~~0.0.1.0',↩
'Rsat.FileServices.Tools~~~~0.0.1.0','Rsat.IPAM.Client.↩
Tools~~~~0.0.1.0',↩                       'Rsat.VolumeActivation.Tools~~~~0.0.1.0',↩
'Rsat.CertificateServices.Tools~~~~0.0.1.0','Rsat.↩
BitLocker.Recovery.Tools~~~~0.0.1.0')
        $val = Get-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdate↩
AU" -Name "UseWUServer" | select -ExpandProperty ↩
UseWUServer -ErrorAction SilentlyContinue
        Set-ItemProperty -Path ↩ "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdate↩
AU" -Name "UseWUServer" -Value 0 -ErrorAction ↩ SilentlyContinue
        Restart-Service wuauserv -ErrorAction SilentlyContinue
    }
    PROCESS {
        foreach ($Component in $Components) {
            $InstallState = (Get-WindowsCapability ↩
-Name $Component -Online -ErrorAction SilentlyContinue)↩
.state
            if ($InstallState -eq "Installed") {
                Write-Verbose "Uninstalling: $Component..."
                Remove-WindowsCapability -Online ↩
-Name $Component -ErrorAction SilentlyContinue
            } else {
                write-verbose "Cannot uninstall $Component ↩
as it is not present on this system."
            }
        }
    }
    END {
        Set-ItemProperty -Path "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdate↩
AU" -Name "UseWUServer" -Value $val -ErrorAction ↩ SilentlyContinue
        Restart-Service wuauserv -ErrorAction SilentlyContinue
    }
}
Listing 7-11

ManageRsat.ps1

When creating the Win32 application in the Intune portal, at stage two of the application creation wizard “Program,” you should enter the install command line for a function accepting parameters (as shown previously in this chapter in Listing 7-10).

The full installation command line is shown in Listing 7-12.
"C:WindowsSysnativeWindowsPowerShellv1.0powershell.exe" ↩
-noprofile -executionpolicy Bypass -command "& ↩ { . .ManageRSAT.ps1; Install-RSATCapabilities }"
Listing 7-12

Calling the Install-RSATCapabilities function from the ManageRSAT.ps1 script

The uninstall command line is similar, except this time you call the uninstall function Uninstall-RSATCapabilities, as shown in Listing 7-13.
"C:WindowsSysnativeWindowsPowerShellv1.0powershell.exe" ↩
-noprofile -executionpolicy Bypass -command "& ↩ { . .ManageRSAT.ps1; uninstall-RSATCapabilities }"
Listing 7-13

Calling the Uninstall-RSATCapabilities function from the ManageRSAT.ps1 script

Figure 7-2 shows the completed install and uninstall command line at stage two of the Intune Win32 application creation wizard.

A screenshot of the windows app. It depicts 6 steps. Under the program step, it has options such as install and uninstall command, install behavior, and device restart behavior.

Figure 7-2

The install command and uninstall command have been completed

Figure 7-3 shows a portion of the Win32 application summary screen in the Intune portal where you can view the complete install and uninstall commands.

A screenshot of the win 32 application. It has an install and uninstall command under the program. The create button at the bottom is highlighted.

Figure 7-3

The full commands used can be seen in the application summary

This deployment also uses a PowerShell custom detection rule and demonstrates the power and flexibility you can only get when using a PowerShell detection rule. It is shown in Listing 7-14.
$Components = @('Rsat.Dns.Tools~~~~0.0.1.0',↩
'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0',↩
'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0', ↩ 'Rsat.DHCP.Tools~~~~0.0.1.0','Rsat.FileServices.↩
Tools~~~~0.0.1.0','Rsat.IPAM.Client.Tools~~~~0.0.1.0',↩ 'Rsat.VolumeActivation.Tools~~~~0.0.1.0','Rsat.↩
CertificateServices.Tools~~~~0.0.1.0','Rsat.BitLocker.↩
Recovery.Tools~~~~0.0.1.0')
 foreach ($Component in $Components) {
    $InstallState = (Get-WindowsCapability -Name ↩
$Component -Online -ErrorAction SilentlyContinue).state
        if ($InstallState -eq "Installed") {
            $Result = $true
        } else {
            $result = $false
            break
        }
}
if ($result) {
    write-host "Installed!"
}
Listing 7-14

The PowerShell script used for the RSAT deployment custom detection rule

Summary

In this chapter, you learned about the virtual folder Sysnative, and understood why it was important to use it when creating the script install or uninstall commands.

You then learned that not all scripts are the same; some have entry points, some have functions, and some are either of those types with parameters. You also learned how to build the correct install command line depending on which of those script types it was.

Finally, you saw an example of deploying the RSAT (Remote Server Administration Tools) that contained both an install and uninstall function, and what the install command lines would look like.

The next chapter looks at a fully functional deployment template that can be used as-is or modified for your own needs.

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

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