Using bulk actions for renaming Windows devices

A few months ago, I did a blog post about the different ways of renaming Windows 10 devices. This week is a follow-up on that post, as it will also be about renaming Windows devices. This time it’s about using the recently introduced functionality to perform Bulk actions on devices. Those Bulk actions include the action to rename Windows 10 devices in bulk. That Bulk action is also available as a single action on a device and is currently not available for hybrid Azure Active Directory joined devices, nor available for co-managed devices. In this post I’ll show how to perform this action by using the Microsoft Endpoint Manager admin center, followed by using the Microsoft Graph Explorer. I’ll end this post by showing an example using PowerShell and the Microsoft Graph API.

Rename Windows devices using the Microsoft Endpoint Manager admin center

Now let’s start by having a look at using a Bulk action for renaming a Windows 10 device by using the Microsoft Endpoint Manager admin center. This method is – in my opinion – always the first step towards automating an action. The following 9 steps walk through the Bulk action for renaming Windows 10 devices. While performing these steps make sure to use Microsoft Edge and to turn on the Developer tools (Ctrl + Shift + I), as that will help with identifying the Graph request that should be used for automation purposes.

  1. Open the Microsoft Endpoint Manager admin center portal and navigate to Devices All devices > Bulk Device Actions to open the Bulk device actions blade
  2. On the Basics page, provide the following information (see Figure 1) and click Next
  • OS: Select Windows
  • Device action: Select Rename
  • Enter new name: Provide a new naming conform the provided guidelines
  1. On the Devices page, click Select devices to include to select the devices to rename and click Next
  2. On the Review + create page, review the provided information and click Create

Verify request information using the Microsoft Graph Explorer

When following the Bulk action via the Network trace in the Developer tools, it shows the executeAction action that will perform the actual action. The most relevant parts of that action are shown below, as Figure 2 shows the request URL and Figure 3 shows the request payload. That combination is needed for automation purposes.

A closer look shows that the executeAction action is used as the request location to post the request.

https://graph.microsoft.com/beta/deviceManagement/managedDevices/executeAction

That request requires a request body to supply a JSON representation of the different properties. A closer look at that JSON payload shows the properties action, actionName, deviceIds, deviceName, platform, realAction and restartNow. The good thing is that these properties are pretty self explanatory, especially in combination with the action that was performed to retrieve this information. It’s good to specifically point out that the deviceIds property is an array that can currently contain up to a 100 devices and that the deviceName property should contain the naming format for the different applicable devices.

{
	action: "setDeviceName",
	actionName: "setDeviceName",
	deviceIds: ["d8cd02c1-9443-4ad0-8681-937c2e6d7607"],
	deviceName: "CLDCLN%RAND:2%",
	platform: "windows",
	realAction: "setDeviceName",
	restartNow: false
}

The next step toward automating this Bulk action is by trying the correct request URL and request payload via the Microsoft Graph Explorer, as that’s an easy method to try Graph API requests. Simply sign-in, change the action to POST, add the request URL, add the request payload (as shown in Figure 4) and click Run Query.

Note: The application requires the scope DeviceManagementManagedDevices.PrivilegedOperations.All.

Running the query will return a bulkManagedDeviceActionResult result type. That result type provides a JSON representation of the status properties. Those status properties include successfulDeviceIds, failedDeviceIds, notFoundDeviceIds and notSupportedDeviceIds. The good thing is that these properties are also pretty self explanatory. A simple method to verify this behavior is by throwing in some random deviceIds. Those deviceIds should end up as part of the notFoundDeviceIds.

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#microsoft.graph.bulkManagedDeviceActionResult",
    "successfulDeviceIds": [
        "d8cd02c1-9443-4ad0-8681-937c2e6d7607"
    ],
    "failedDeviceIds": [],
    "notFoundDeviceIds": [],
    "notSupportedDeviceIds": []
}

Rename Windows devices using PowerShell and the Microsoft Graph API

After verifying the request URL and the request payload, the last step toward automating this Bulk action is putting it all together in a PowerShell script. I’m going to provide a really simple example that would still require administrator interaction, but does show how it can be achieved. That example is shown below and basically performs the following actions:

  • Install the PowerShell SDK for Microsoft Intune Graph API (if it’s not installed).
  • Connect with the Graph API, which will prompt the administrator for credentials.
  • Set the required variables for the request URL and the request payload.
  • Invoke the Graph API request with the configured variables.
#Install PowerShell SDK for Microsoft Intune Graph API
If ((Get-Module Microsoft.Graph.Intune) -eq $null) {
    Install-Module -Name Microsoft.Graph.Intune
}

#Connect to Microsoft Graph
$ConnectGraph = Connect-MSGraph

#Set the request URL
$URL = "https://graph.microsoft.com/beta/deviceManagement/managedDevices/executeAction"

#Set the JSON payload
$JSONPayload = @"
{
	action: "setDeviceName",
	actionName: "setDeviceName",
	deviceIds: ["d8cd02c1-9443-4ad0-8681-937c2e6d7607"],
	deviceName: "CLDCLN%RAND:2%",
	platform: "windows",
	realAction: "setDeviceName",
	restartNow: false
}
"@

#Invoke the Microsoft Graph request
Try {        
    Invoke-MSGraphRequest -HttpMethod POST -Url $URL -Content $JSONPayload -Verbose -ErrorAction Stop
}
Catch {
    Write-Output "Failed to rename the Windows devices"
} 

When the PowerShell script was successfully executed it will also return the bulkManagedDeviceActionResult result type, as shown in Figure 5. Simple improvements to this PowerShell script would be to remove the administrator interaction, add the deviceIds to a variable and query for the required devices.

More information

For more information about renaming Windows devices and , refer to the following articles:

Working with (custom) detection rules for Win32 apps

After my post of last week about Working with (custom) requirements for Win32 apps only one configuration subject of Win32 apps is left that I’ve discussed in detail, the detection rules for Win32. The format of this week is similar to that post and to previous posts about the different configuration subjects of Win32 apps. Detection rules must be used to determine the presence of a Win32 app. A Win32 app can have multiple detection rules. In that case every detection rule must be met to detect the app. That will help with making sure that the app installation will only be started when the app is not yet installed. In this post I’ll start with going through the different detection rule formats and I’ll end this post by looking at the administrator experience on a Windows device.

Detection rule

Now let’s start by having a look at the available detection rules of a Win32 app in Microsoft Intune. Let’s do that by first navigating to the location in the Microsoft Endpoint Manager admin center portal that provides the different detection rule format options for Win32 apps.

  1. Open the Microsoft Endpoint Manager admin center portal and navigate to Apps Windows > Windows apps to open the Windows – Windows apps blade
  2. On the Windows – Windows apps blade, select a Win32 app (or create a new one) and click Properties > Detection rules to open the Detection rules blade

On the Detection rules blade, the different detection rule formats of Win32 apps are shown. Those detection rule formats are categorized as mentioned below.

  1. Manually configure detection rules: This detection rule format enables the administrator to use a MSI product code, file or folder information or registry information for detecting the app.
  2. Use custom detection rules: This detection rule format enables the administrator to use a custom script for detecting the app.

The first category contains manual configurable detection rules. The manual configurable detection rules contains three different rule types that can be used to indicate the presence op the app. The first rule type in that list is MSI. That rule type enables the administrator to create a detection rule that must detect a specific MSI, or even a specific MSI version. This detection rule type can only be used once. A detection rule of this type requires the following configuration properties.

  • MSI product code – This property enables the administrator to configure the specific MSI product code that should be used to detect the installation of the app. When the installation contains an MSI, and this rule type is used, this property will be automatically populated.
  • MSI product version check – This property enables the administrator to configure also a specific version of the MSI product code that should be used to detect the installation of the app.

The second rule type in that list is File. That rule type enables the administrator to create a detection rule that must detect a specific file or folder, date, version, or size to determine the installation of the Win32 app. A detection rule of this type requires the configuration properties as mentioned below. This rule type is with its configuration properties nearly equal to the File rule type within requirement rules.

  • Path – This property enables the administrator to configure the full path of the folder that contains the file or folder that should be used to detect the installation of the app.
  • File or folder – This property enables the administrator to configure the file or folder that should be used to detect the installation of the app.
  • Detection method – This property enables the administrator to configure the method that should be used to detect the installation of the app. The following self explaining options are available.
    • File or folder exists
    • Date modified
    • Date created
    • String (version)
    • Size in MB
  • Associated with a 32-bit app on 64-bit clients – This property enables the administrator to configure that path environment variables are in 32-bit (yes) or 64-bit (no) context on 64-bit clients.

The third rule type in that list is Registry. That rule type enables the administrator to create a detection rule that must detect a specific registry setting based on value, string, integer, or version to determine the installation of the Win32 app. A detection rule of this type requires the configuration properties as mentioned below. This rule type is with its configuration properties nearly equal to the Registry rule type within requirement rules.

  • Key path – This property enables the administrator to configure the full path of the registry entry containing the value that should be used to detect the installation of the app.
  • Value name – This property enables the administrator to configure the name of the registry value that should be used to detect the installation of the app. When this property is empty, the detection will happen on the default value. The default value will also be used as detection value if the detection method is other than file or folder existence.
  • Detection method – This property enables the administrator to configure the method that should be used to detect the installation of the app. The following self explaining options are available.
    • Key exists
    • Key does not exist
    • String comparison
    • Version comparison
    • integer comparison
  • Associated with a 32-bit app on 64-bit clients – This property enables the administrator to configure that the search is in the 32-bit registry (yes) or in the 64-bit registry (no) on 64-bit clients

The second category contains custom scriptable detection rules. That is the most advanced rule format. That rule format enables the administrator to create detection rules that can check on basically anything that can be scripted, as long as the script has the correct output. A detection rule of that type requires the configuration properties as mentioned below. This rule type has some similarities with the Script rule type within the requirement rules. The main difference is with the output of this rule type as it’s more limited. In this rule type the detection of the Win32 app is based on the execution success of the script in combination with any output. It doesn’t matter what the output is.

  • Script name – This property enables the administrator to provide a name for the script.
  • Script file – This property enables the administrator to select a script that will be used to detect the installation of the app. When the script exit code is 0 and STDOUT contains any data, the app is detected (see table below for a summary).
  • Run script as 32-bit process on 64-bit clients – This property enables the administrator to configure the script to run in a 32-bit process (yes) or in a 64-bit process (no) on 64-bit clients.
  • Enforce script signature check – This property enables the administrator to configure that the script signature should be verified (yes) or that the signature verification should be skipped (no).
Exit codeData read from STDOUTDetection state
0EmptyNot detected
0Not emptyDetected
Not zeroEmptyNot detected
Not zeroNot EmptyNot detected

Administrator experience

Let’s end this post by having a look at the behavior of custom script detection rules on a Windows 10 device. The most advanced option. To do that I’ve used a really simple script that will detect the installation of Foxit Reader by looking at a specific directory. That can also be achieved by using a File rule type, but it’s an easy example for showing the functionality of custom script rule types. When the specific path is found, the script will output “Found it!“. That means that the detection rule will provide an output, when the detection was successful.

if (Test-Path "$($env:ProgramFiles)\Foxit Software\Foxit Reader\FoxitReader.exe") {
    Write-Host "Found it!"
}

When adding this script as a detection rule to a Win32 app and deploying that app as a required app to a user or a device, the installation process can be followed very good in the IntuneManagedExtension.log. That includes the process of detecting the installation of the app by going through the detection rule(s). Below is that example. It walks through the process of checking the detection rule(s) of the Win32 app. It shows the start of the script, the result of the script and following the detection state of the Win32 app (based on the result of the detection rule).

More information

For more information about the Win32 app functionality in Microsoft Intune, refer to the documentation about Intune Standalone – Win32 app management.

Working with (custom) requirements for Win32 apps

A few months ago I did a post about Working with the restart behavior of Win32 apps and a few months before that I did a post about Working with Win32 app dependencies. This week is similar to those post. This week is also about Win32 apps, but this week it’s about working with requirements for Win32 apps. Requirements can be used to make sure that the Win32 app will only install on a device that meets specific requirements. That means that requirements for Win32 apps, bring a lot of options and capabilities, which enable a lot of scenarios. Think about deploying a Win32 app to a user group and only installing on a specific device brand, type, or model. That can be achieved by using requirements. In this post I’ll quickly go through the different standard available requirement types, followed by a more detailed look at the custom script requirement type. I’ll end this post by looking at the administrator experience on a Windows device.

Requirement type

Now let’s start by having a look at the standard available requirement types within Microsoft Intune. Let’s do that by first navigating to the location in the Microsoft Endpoint Manager admin center portal that provides the different requirement options for Win32 apps.

  1. Open the Microsoft Endpoint Manager admin center portal and navigate to Apps Windows > Windows apps to open the Windows – Windows apps blade
  2. On the Windows – Windows apps blade, select a Win32 app (or create a new one) and click Properties > Requirements to open the Requirements blade

On the Requirements blade, the different standard available Win32 app requirement types are shown. Those requirement types are shown and explained below.

  1. Operating system architecture: This requirement enables the administrator to select the required architecture (32-bit | 64-bit) of the operating system that is needed for the Win32 app. This is a required configuration.
  2. Minimum operating system: This requirement enables the administrator to select the minimum operating system version that is needed to install the Win32 app. This is a required configuration.
  3. Disk space required (MB): This requirement enables the administrator to configure the free disk space that is needed on the system drive to install the Win32 app. This is an optional requirement.
  4. Physical memory required (MB): This requirement enables the administrator to configure the physical memory (RAM) that is required to install the Win32 app. This is an optional requirement.
  5. Minimum number of logical processors required: This requirement enables the administrator to configure the minimum number of logical processors that are required to install the Win32 app. This is an optional requirement.
  6. Minimum CPU speed required (MHz): This requirement enables the administrator to configure the minimum CPU speed that is required to install the Win32 app. This is an optional requirement.
  7. Configure additional requirement rules: See below.

The six requirements mentioned above are the standard available and easy to configure Win32 app requirement types. Besides those requirements, it’s also possible to add more advanced requirement types (as shown with number 7 above). The first requirement in that list of more advanced requirement types is File. That requirement type enables the administrator to create requirement rule that must detect a file or folder, date, version, or size. A requirement rule of that type requires the following configuration properties.

  • Path – This property enables the administrator to configure the full path of the folder that contains the file or folder that should be detected.
  • File or folder – This property enables the administrator to configure the file or folder that should be detected.
  • Property – This property enables the administrator to configure the type of rule that should be used to validate the presence of the Win32 app. The following self explaining options are available.
    • File or folder exists
    • File or folder does not exist
    • Date modified
    • Date created
    • String (version)
    • Size in MB
  • Associated with a 32-bit app on 64-bit clients – This property enables the administrator to configure that path environment variables are in 32-bit (yes) or 64-bit (no) context on 64-bit clients.

The second requirement in that list of more advanced requirement types is Registry. That requirement type enables the administrator to create requirement rule that must detect a registry setting based on value, string, integer, or version. A requirement rule of that type requires the following configuration properties.

  • Key path – This property enables the administrator to configure the full path of the registry entry containing the value that should be detected.
  • Value name – This property enables the administrator to configure the name of the registry value that should be detected. When this property is empty, the detection will happen on the default value. The default value will also be used as detection value if the detection method is other than file or folder existence.
  • Registry key requirement – This property enables the administrator to configure the type of registry key comparison that should be used to determine how the requirement rule is validated. The following self explaining options are available.
    • Key exists
    • Key does not exist
    • String comparison
    • Version comparison
    • integer comparison
  • Associated with a 32-bit app on 64-bit clients –This property enables the administrator to configure that the search is in the 32-bit registry (yes) or in the 64-bit registry (no) on 64-bit clients.

The third requirement in that list of more advanced requirement types is Script. That is the most advanced requirement type. That requirement type enables the administrator to create requirement rules that can check on basically anything that can be scripted, as long as the script has the correct output. A requirement rule of that type requires the following configuration properties.

  • Script name – This property enables the administrator to provide a name for the script.
  • Script file – This property enables the administrator to select a script that will be used to verify custom requirements. When the script exit code is 0, Intune will detect the STDOUT in more detail.
  • Run script as 32-bit process on 64-bit clients – This property enables the administrator to configure the script to run in a 32-bit process (yes) or in a 64-bit process (no) on 64-bit clients.
  • Run this script using the logged on credentials – This property enables the administrator to configure the script to run using the credentials of the signed in user (yes) or using the SYSTEM context (no).
  • Enforce script signature check – This property enables the administrator to configure that the script signature should be verified (yes) or that the signature verification should be skipped (no).
  • Select output data type – This property enables the administrator to configure the data type that is used to determine a requirement rule match. The following self explaining options are available.
    • String
    • Date and Time
    • Integer
    • Floating Point
    • Version
    • Boolean

This advanced requirement type enables an administrator to check on basically anything. Based on the information provided above, the script should run successful (exit code 0) and provide an output in the selected data type (string, date and time, integer, floating point, version or boolean).

Administrator experience

Let’s end this post by having a look at the behavior of requirement rules a on a Windows 10 device. To do that I’ve used a really simple script that will check the manufacturer of the device. When the manufacturer matches the specified manufacturer, the script will output “Found it!“. That means that the requirement rule should look for output data of the type String. And more specifically a String that equals “Found it!“.

if ((Get-WmiObject Win32_ComputerSystem).Manufacturer -eq "Microsoft Corporation") {
    Write-Output "Found it!" 
}

When adding this script as a requirement rule to a Win32 app and deploying that app as a required app to a user or a device, the installation process can be followed very good in the IntuneManagedExtension.log. That includes the process of verifying the requirement rules that should be checked. Below is that example. It walks through the process of checking the requirement rules for the Win32 app. It shows the start of the script, the result of the script and following the applicability of the Win32 app (based on the result of the requirement rule).

More information

For more information about the Win32 app functionality in Microsoft Intune, refer to the documentation about Intune Standalone – Win32 app management.

Windows 10 MDM (PowerShell) scripting

A long, long time ago, I wrote about the MDM WMI Bridge provider. Nowadays I notice that the MDM WMI Bridge provider is still an unknown configuration layer for many IT admins. That’s why I’ve decided to do another post about the MDM WMI Bridge provider. A quick reminder: the MDM WMI Bridge provider is used to map the CSPs to WMI. This time my post is more focused on providing some examples and guidance. Besides that it’s also a nice addition on my latest posts about Windows 10 MDM configurations, policy refresh and troubleshooting. I’ll start this post by showing how to configure device settings and I’ll end this post by showing how to trigger device actions.

Keep in mind that this post is about configuring device settings. That means that every action requires to run in SYSTEM context. I advise to use PsExec for executing the scripts and tools mentioned in this post

Configuring device settings

The easiest starting point for everything related to WMI is Windows Management Instrumentation Tester (in short wbemtest). As an example I’ll take last weeks post to another level by also looking at the Reboot CSP for this post. The starting point for that is the MDM_Reboot_Schedule01 class.

Let’s start at the beginning. The root\cimv2\mdm\dmmap namespace, is the namespace that contains all the information regarding MDM in WMI. This is the MDM WMI Bridge provider. This namespace contains the WMI classes that map to CSP nodes. There are 3 methods available to get the available WMI classes:

  1. The docs about the MDM Bridge WMI provider
  2. Use wbemtest to connect to the namespace and click Enum Classes
  3. User PowerShell (Get-CIMClass) to enumerate the available classes

For this example I’ll use wbemtest to connect to the root\cimv2\mdm\dmmap namespace and to enumerate the available classes. This tool is an easy method for showing information via a UI. When knowing the exact class, it’s also possible to directly connect to that class by using Open Class instead of Enum Classes.

In this example, I know the class, which enables me to open the specific MDM_Reboot_Schedule01 class. Connecting to that class, provides me with the available properties (DailyRecurrent, InstanceID, ParentID, Single). These properties are well documented in the earlier mentioned article. In some scenarios, the classes and/or properties are not yet documented. In those scenarios wbemtest can be a very good starting point for getting the required information.

Now the available classes and properties are known, it’s time to have a look at the available options. As it’s basically standard WMI, at this point, there are also the standard WMI PowerShell scripting options available (Get, New, Remove and Modify). Below are some basic examples of using the CimCmdlets for WMI. Having mentioned that, I also deliberately left out some real New-CimInstance and Remove-CimInstance examples, as the example that I use for this post doesn’t support those actions. The MDM_Reboot_Schedule01 class already contains an instance and can’t contain multiple instances. Below are some generic example of using those cmdlets.

#Enumerate available instances
Get-CimInstance -Namespace $namespaceName -ClassName $className
#Create a new instance
New-CimInstance -Namespace $namespaceName -ClassName $className -Property @{}
#Get a specific instance 
$instanceObject = Get-CimInstance -Namespace $namespaceName -ClassName $className -Filter "ParentID='$parentID' and InstanceID='$instanceID'"

#Remove a specific instance
Remove-CimInstance -CimInstance $instanceObject

That basically means that it’s only possible to modify the available instance in the MDM_Reboot_Schedule01 class. That instance is Schedule. The Schedule instance can be adjusted by adding a value to the Single property and/ or the DailyRecurrent property. Those properties are used to actually create the specified schedule. Just like in the CSP configuration, the date and time value is ISO8601 and in UTC. The example below will get the Schedule instance in the root\cimv2\mdm\dmmap namespace, and will modify the Single property to configure a new single scheduled reboot.

#Declare variables
$namespaceName = "root\cimv2\mdm\dmmap"
$className = "MDM_Reboot_Schedule01"
$parentID = "./Vendor/MSFT/Reboot"
$instanceID = "Schedule"
$singleSchedule = "2019-10-01T22:00:00Z"

#Get a specific instance
$instanceObject = Get-CimInstance -Namespace $namespaceName -ClassName $className -Filter "ParentID='$parentID' and InstanceID='$instanceID'"

#Adjust a specific property
$instanceObject.Single = $singleSchedule

#Modify an existing instance
Set-CimInstance -CimInstance $instanceObject

Triggering device actions

Besides configuring settings via the MDM WMI Bridge provider, it’s also possible to trigger actions via the provider. When still looking at the Reboot CSP, that CSP also contains a node to execute RebootNow. RebootNow will trigger a reboot within 5 minutes. That action is available within the Intune console as a Restart action for a device. The nice thing is that this action can also be triggered via the MDM WMI Bridge provider.

Let’s skip the beginning about connecting to the WMI namespace and directly navigate to the required WMI class. The MDM_Reboot class. When connecting to the MDM_Reboot class, by using wbemtest, it’s immediately clear why wbemtest is such a nice and easy tool. After connecting to the class, wbemtest immediately provides an overview of the available methods. In this case the RebootNowMethod method.

Triggering the RebootNowMethod method, via PowerShell, will provide an alternative (and very creative) method for rebooting a device. This method is well documented in the earlier mentioned documentation. In some scenarios, the methods are not yet documented. In those scenarios wbemtest can be a very good starting point for getting the required information.

The RebootNowMethod method can be triggered by getting the available instance of the MDM_Reboot class. That instance is Reboot. That instance can be used to trigger the RebootNowMethod method. The example below will get the Reboot instance in the root\cimv2\mdm\dmmap namespace, and will trigger the RebootNowMethod method to trigger a reboot within five minutes.

#Declare variables
$namespaceName = "root\cimv2\mdm\dmmap"
$className = "MDM_Reboot"
$parentID = "./Vendor/MSFT/Reboot"
$instanceID = "Reboot"
$methodName = "RebootNowMethod"

#Get a specific instance
$instanceObject = Get-CimInstance -Namespace $namespaceName -ClassName $className -Filter "ParentID='$parentID' and InstanceID='$instanceID'"

#Trigger specific method
Invoke-CimMethod -InputObject $instanceObject -MethodName $methodName

Now let’s end this post by having a look at the effect of triggering the RebootNowMethod method. Below is an example of a simplified version (read: a one-liner) of the previous script. Just for demo purposes. After triggering that the RebootNowMethod method, the device will immediately provide a popup with a reboot notification.

More information

For more information about PowerShell and the MDM WMI Bridge provider, have a look at this article about Using PowerShell scripting with the WMI Bridge Provider.

Simple method for adding notifications to scripted installations

This week is focused on the end-user experience. More specifically, the end-user experience for scripted actions. Especially when deploying apps, or performing other scripted actions, by using the PowerShell functionality, there could be actions of interest for the end-user.In that case I would like to notify the end-user. The app deployment functionality already provides the option to display notifications to the end-user and in this post I’ll show a simple, but effective method, to also display notifications to scripted installations. That can be a nice addition to this post about combining the powers of the Intune Management Extension and Chocolatey. In this post I’ll provide an updated script, followed by the required configuration steps. I’ll end this post with the end-user experience.

Script

The first step is to create a PowerShell script that can be used to install Chocolaty packages and to show notifications to the end-user after a successful installation. The following script provides the exact mentioned functionality, nothing more, nothing less, and the script is documented to provide some more details about the exact actions. The script uses the BurntToast module, which is available in the PowerShell Gallery, to display notifications.

Note: The BurntToast module, which is used, will only work for the logged-on user. For functionality in SYSTEM context, additional adjustments are required.

Configuration

The next step is to configure the PowerShell script in Microsoft Intune. The script must run in SYSTEM context to easily install new Windows Features. To upload the script, follow the five steps below. After uploading the script, simply assign the script to the required devices. I deliberately mentioned devices, as I’m using a security group that filters on the version of Windows 10. The good thing is that nowadays these scripts can be assigned to devices and that users are not required to be logged on first.

1 Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts to open the Device configuration – PowerShell scripts blade;
2 On the Device configuration – PowerShell scripts blade, click Add to open the Script Settings blade;
3a Notification-AddPowerShellScriptOn the Add PowerShell script blade, provide the following information and click Create;

  • Name: Provide a valid name for the PowerShell script;
  • Description: (Optional) Provide a description for the PowerShell script;
  • Script location: Browse to the created PowerShell script;
  • Settings: See step 3b;

Note: The script must be less than 200 KB.

3b Notification-ScriptSettingsOn the Script Settings blade, provide the following configuration and click OK;

  • Run the script using the logged on credentials: Yes;
  • Enforce script signature check: No;
  • Run script in 64 bit PowerShell: Yes;

Explanation: This configuration will make sure that the script will run by using the user credentials on 32-bit and 64-bit devices.

Note: Keep in mind that the script will be running by using the user credentials, which will require the user to be local administrator for installing the different apps.

End-user experience

Let’s end this post by having a look at the end-user experience. This time I choose to go for an animated gif, as that will provide the best example of the end-user experience. Below is an example of the script installing 7-Zip and Notepad++.

Notification-Experience

More information

For more information about the BurtToast module, please refer to the PowerShell Gallery.

Simply enabling Windows Sandbox

This blog post uses Containers-DisposableClientVM, to enable the Windows Sandbox feature on Windows 10 devices. This is available in Windows 10 Insider build 18305 or later.

This week is all about enabling a recently introduced Windows Feature. That Windows Feature is Windows Sandbox. Windows Sandbox is a lightweight desktop environment that is specifically created for safely running applications in isolation. It provides an isolated, temporary, desktop environment where users can run untrusted software without the fear of lasting impact to their device. Any software installed in Windows Sandbox stays in the sandbox and cannot affect the host. The installed software is permanently deleted, once Windows Sandbox is closed. Windows Sandbox is part of Windows 10 (Pro and Enterprise) Insider build 18305 or later. In this post I’ll show how to use Microsoft Intune to enable Windows Sandbox, followed by the end result.

Script

Let’s start  by looking at the PowerShell script that can be used to enable the Windows Sandbox feature. The following PowerShell script can be used to basically enable any Windows Feature, but will be used in this post to specifically install the Windows Sandbox feature.

Note: When using a virtual machine, nested virtualization must be enabled for that virtual machine. That can be achieved by using the following PowerShell cmdlet on the host machine: Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true.

Configuration

The next step is to configure the PowerShell script in Microsoft Intune. The script must run in SYSTEM context to easily install new Windows Features. To upload the script, follow the five steps below. After uploading the script, simply assign the script to the required devices. I deliberately mentioned devices, as I’m using a security group that filters on the version of Windows 10. The good thing is that nowadays these scripts can be assigned to devices and that users are not required to be logged on first.

1 Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts;
2 On the Device configuration – PowerShell scripts blade, click Add script to open the Script Settings blade;
3a EWS-AddPowerShellScriptOn the Add PowerShell script blade, provide the following information and click Settings to open the Script Settings blade;

  • Name: Provide a valid name for the PowerShell script;
  • Description: (Optional) Provide a description for the PowerShell script;
  • Script location: Browse to the created PowerShell script;
  • Settings: See step 3b;

Note: The script must be less than 200 KB (ASCII) or 100 KB (Unicode).

3b EWS-ScriptSettingsOn the Script Settings blade, provide the following configuration and click OK to return to the PowerShell script blade;

  • Run the script using the logged on credentials: No;
  • Enforce script signature check: No;
4 Back on the Add PowerShell script blade, click Create.

End result

Now let’s end this post by looking at the results. To verify a success, simply start Windows Sandbox. That Windows Feature should be available now. To verify a success from a Microsoft Intune perspective, either check the status of the PowerShell script in the Azure portal , or look at the AgentExecutor.log and IntuneManagementExtension.log on the device.

EWS-Example

Note: By using PowerShell, at this moment, Windows Sandbox can also be enabled on not supported devices (devices without virtualization capabilities), .

More information

For more information regarding Windows Sandbox and PowerShell scripts in Microsoft Intune, please refer to the following articles:

Simply installing the Windows 10 Accounts extension for Google Chrome by using PowerShell

This week is all about simply automatically installing the Windows 10 Accounts extension for Google Chrome. About a year ago I showed that the extension is required when using conditional access and I also showed earlier that it’s possible to use ADMX ingestion to configure Google Chrome. However, the latter is always the easiest method. It actually might be a bit complicated for a simple configuration. That’s why I’m going a different road this time. This time I’m going for a small PowerShell script that will create a registry key and value. In this post I’ll show how to create the PowerShell script, how to assign it by using Microsoft Intune and the end result in Google Chrome.

Create PowerShell script

As I’ve decided to use a PowerShell script to install the Windows 10 Accounts extension for Google Chrome, together with Google Chrome, this section will explain the variables and actions used in the script. For installing Google Chrome, I’ll reuse a PowerShell script that I explained in this post about Combining the powers of the Intune Management Extension and Chocolatey.

Script variables

The PowerShell script contains a few variables that are used to make sure that the Windows 10 Accounts extension will be installed. Those variables together are actually a registry key and value. That means that the variables block on top of the script (see script snippet section) at least contains the values as shown below. The registry key and value will trigger the installation of the Windows 10 Accounts extension and is the same registry key and value that would otherwise be created by the ADMX configuration.

Path HKLM\Software\Policies\Google\Chrome\ExtensionInstallForcelist
Name 1
Type REG_SZ (String)
Data ppnbnpeolgkicgegkbkbjmhlideopiji;https://clients2.google.com/service/update2/crx

Script actions

The PowerShell script contains a few actions that it should perform to complete the required activities of installing Google Chrome and the required Windows 10 Accounts extension. It contains the following actions that can be found in the different try-catch blocks (see script snippet section).

  1. Install Chocolatey if it’s not installed;
  2. Install Google Chrome by using Chocolatey (it will automatically check if it’s already installed);
  3. Create the required registry path if it doesn’t exist;
  4. Create the required registry key if it doesn’t exist.

Script snippet

The PowerShell script is shown below and should pretty much explain itself.

Configure PowerShell script

The next step is to configure the PowerShell script in Microsoft Intune. To upload the script, follow the next five steps. After uploading the script, simply assign the script to the required users and/or devices.

1 Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts;
2 On the Device configuration – PowerShell scripts blade, click Add script to open the Script Settings blade;
3 ChromeExtension-PowerShell-IntuneOn the Add PowerShell script blade, provide the following information and click Settings to open the Script Settings blade;

  • Name: Provide a valid name for the PowerShell script policy;
  • Description: (Optional) Provide a description for the PowerShell script policy;
  • Script location: Browse to the PowerShell script.

Note: The script must be less than 10 KB (ASCII) or 5 KB (Unicode).

4 ChromeExtension-ScriptSettings-IntuneOn the Script Settings blade, provide the following configuration and click OK to return to the PowerShell script blade;

  • Run the script using the logged on credentials: No;
  • Enforce script signature check: No;

Note: Configure Run the script using the logged on credentials to No means that the PowerShell script will run in SYSTEM context;

5 Back on the Add PowerShell script blade, click Create.

End result

Now let’s end this post by looking at the end result. I’ll do that by showing a screenshot of Google Chrome. Below is a screenshot of Google Chrome showing the policy page, which shows the configured policy, and it also shows the installed Windows 10 Accounts extension (blue Windows icon on the top right).

ChromeExtension

More information

Fore more information related to conditional access and the requirements for Google Chrome, please refer to this article about Conditional Access Technical Reference | Client apps condition.

Using the Intune Management Extension, on a 64-bit platform, for a very happy New Year!

Let’s start the New Year with a quick tip about the Intune Management Extension, which is used for running PowerShell scripts, in combination with a 64-bit platform. The Intune Management Extension is 32-bit and will run PowerShell scripts in a 32-bit environment. This is not always the desired behavior. Actually, many activities and/or cmdlets, require a 64-bit environment. In this blog post I’ll provide a simple workaround, to run the PowerShell scripts in a 64-bit environment, and I’ll show the behavior of that simple workaround.

The (example) script

Now let’s start by looking at that simple workaround. That workaround is actually a simple addition to a script that starts the same script, by using the 64-bit environment of PowerShell. This is achieved by starting with the following assumptions:

  • The script  doesn’t have to deal with parameters – This saves me from doing difficult with providing parameters to it;
  • The script should only switch on a 64-bit platform running a 32-bit process – This makes sure that it won’t break on a 32-bit platform. That can be achieved by using $ENV:PROCESSOR_ARCHITEW643. That environment variable is set when running a 32-bit process on a 64-bit platform;
  • The script needs the right location of PowerShell – This makes sure that this time the 64-bit environment of PowerShell will be started. That can be achieved by using SysNative. That alias is used to point a 32-bit process to C:\Windows\System32;
  • The script needs the right location of the script – This makes sure that the same script is started again. That can be achieved by using $PSCOMMANDPATH. That automatic variable contains the full path and file name of the script that is being run.

These four assumptions bring me to the following small script snippet that can be added to the top of any script. For looking at the results, I’ve added an additional line at the beginning and the ending of the script snippet. Those additional lines write the environment of the process to a file.

Begin: $ENV:PROCESSOR_ARCHITECTURE” >> “C:\Windows\Temp\Test.txt”
If ($ENV:PROCESSOR_ARCHITEW6432 -eq “AMD64”) {
     Try {
         &”$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe” -File $PSCOMMANDPATH
     }
     Catch {
         Throw “Failed to start $PSCOMMANDPATH”
     }
     Exit
}

“End: $ENV:PROCESSOR_ARCHITECTURE” >> “C:\Windows\Temp\Test.txt”

Important: The Intune Management Extension will only report over the initial script. To also report over the newly started script, you might want to look into building something smart that will monitor the newly start script before exiting the initial script. The example above simply exits the initial script.

The (example) results

Let’s end this post by looking at the example script, mentioned above, when deployed via Microsoft Intune. The example script writes, at the beginning and the ending, an entry to a file named Test.txt. After a successful execution, it contains the following three entries:

  1. 64-resultThe first entry is related to the beginning of the initial script, which is triggered by the Intune Management Extension. At that moment it’s started as a 32-bit process;
  2. The second entry is related to the beginning of the newly started version of the script, which is triggered by the initial script. At that moment it’s started as a 64-bit process;
  3. The third entry is related to the ending of the newly started version of the script. At that moment it successfully went through the complete script as a 64-bit process.

More information

For more information about automatic variables in PowerShell, refer to the documentation About Automatic Variables.

Running scripts on Christmas day (and any other day)

My last blog post of this year will also be about a new (pre-release) feature of Configuration Manager, version 1710. This post will be all about the ability to create and run scripts from the Configuration Manager administration console. To be correct, the ability to create and run scripts was added in Configuration Manager, version 1706, and Configuration Manager, version 1710, added the ability to use parameters with those scripts. It completed the functionality.  My Christmas day present for the community is a walkthrough through this functionality and how it runs on the client device. After reading this post you should be able to understand how your script can create the output and how you can find the correct GUIDs to follow the activity on the client device.

Introduction

Starting with Configuration Manager, version 1706, it’s possible to run PowerShell scripts, via the Configuration Manager console, directly on client devices. Configuration Manager, version 1710, completed this functionality by adding the use of parameters. The ability to run PowerShell scripts on client devices is available in the Configuration Manager administration console, via the Run Scripts option. This makes it easier to automate tasks and, in general, the scripts are understood by a large population. It really simplifies building custom tools. Think about all the custom right-click actions that can now be integrated in this functionality. The biggest advantages of using the Run Script option, are the usage of the notification channel and getting good monitoring information. That means, quick results shown in the Configuration Manager administration console. In this post I’ll show the Run Script option by using a simple PowerShell script that will restart a service on the client device. That service is provided to the script via a script parameter.

Script

Now let’s have a look at the Run Script option in the Configuration Manager administration console. I’ll start by looking at a couple of important prerequisites, followed by how to create, approve and run scripts. I’ll end this section by following the script action to the client device.

Prerequisites

Before looking into the possibilities of the Run Script option, the following prerequisites should be in place to take full advantage of the available possibilities:

  • The client device must be running PowerShell version 3.0, or later;
  • The Configuration Manager clients must be running client version 1706, or later;

Create script

Let;s start by looking at the required steps to create a PowerShell script that can become available via the Run Script option. I’ll do that by using a simple script that can restart a service on a client device, based on the provided script parameter. Based on the result, of the script, a specific script output will be returned. The administrative user, creating the script, must have at least the Create permission for SMS Scripts object class.The following six steps walk through the creation of a PowerShell script (step 3 contains the used script):

1 Open the Configuration Manager administration console and navigate to Software Library > Overview > Scripts;
2 On the Home tab, in the Create group, click Create Script to open the Create Script wizard;
3

CS_ScriptOn the Script page, provide the following information and click Next;

  • Script name: Provide a name for the script;
  • Script language: Select PowerShell, as it’s currently the only option;
  • Script: Click Import to browse to a script file and to display it in the wizard. It’s also still possible to edit the imported script;

Note: Declaring variables, as shown with number 1 on the right, will enable an additional page in the wizard for configuring script parameters. The output shown with number 2, can be returned by the client device.

4a

CS_ScriptParametersOn the Script Parameters page, an overview is shown of the provided parameters with the script and it provides the option to set a Default Value. Select the variable and click Edit to adjust the parameter properties (see step 4b). After that, click Next.

Note: This page should provide an overview of the variables as declared in step 3.

4b

CS_ScriptParameterPropertiesOn the Script Parameter Properties dialog box, the information about the name, required status, hidden status and data type is prepopulated based on the declaration of the variable (see step 3). Use this dialog box to configure the following validation properties and click OK:

  • Minimum Length: Specify the minimum number of characters;
  • Maximum Length: Specify the maximum number of characters;
  • RegEx: Specify a regular expression validation;
  • Custom Error: Specify a custom error message.
5 On the Summary page, verify the configuration and click Next;
6 On the Completion page, verify the result and click Close.

Approve script

Before the just created PowerShell script becomes available via the Run Script option, it must be approved by another administrative user with at least the Approve permission for SMS Scripts object class. That will prevent unverified scripts from running on client devices, which should decrease the possibility of running faulty scripts on client devices. The following seven steps walk through the approval of a PowerShell script:

HierarchySettings_GeneralBy default it’s not possible for a script author to approve and/or deny their own scripts. To enable script authors to approve and/or deny their own scripts, open the Configuration Manager administration console and navigate to Administration > Overview > Site Configuration > Site. Now open the Hierarchy Settings and remove the checkbox with Do not allow script authors to approve their own scripts.

Important: It’s strongly advised to only do this in test and/or lab environments.

1 Open the Configuration Manager administration console and navigate to Software Library > Overview > Scripts;
2 Select the just created script and click Approve/Deny, in the Scripts group, on the Home tab, in the Create group, to open the Approve or deny script wizard;
3

ADS_ScriptOn the Script page, verify the script and click Next;

4

ADS_ScriptParametersOn the Script Parameters page, verify the parameters and click Next;

Note: To verify the details of a parameter, select a parameter and click Details. That will show the script parameter properties, as configured during the creation of the script.

5

ADS_ApproveScriptOn the Approve or deny script page, select Approve, provide an Approver Comment (optional) and click Next;

Note: I know this is stating the obvious, but only approve scripts once you’re certain about their behavior. The ability to run scripts on client devices is just really strong and once the script is triggered it will run almost instantly.

6 On the Summary page, verify the configuration and click Next;
7 On the Completion page, verify the result and click Close.

Run script

After approving the just created PowerShell script, it becomes available via the Run Script option. The administrative user, that will run the script, must have at least the Run permission for SMS Scripts object class and the script will be executed in SYSTEM context on the client device. The following six steps walk through running a PowerShell script:

1 Open the Configuration Manager administration console and navigate to Assets and Compliance > Overview > Device Collections;
2

Open a device collection and right-click a client device and select Run Script to open the Run Script wizard;

Note: It’s also possible to start the Run Script wizard by right-clicking a device collection.

3

RS_ScriptOn the Script page, select the just created script and click Next;

Note: The script GUID is interesting for monitoring the script execution.

4

RS_ScriptParametersOn the Script Parameters page, provide a value for the available parameters and click Next.

5 On the Summary page, verify the details and click Next;
6

RS_MonitoringOn the Monitoring page, verify the script output and click Close.

The script output, on the Summary tab, shows the output as provided in the initial script. Within this summary it’s also possible to look at the exit codes and to look at different chart forms. The Script Details tab shows the general information about the script, like the name, version and parameters and the Run Details tab shows the details about the results, like the device name, execution status, exit code and script output.

Monitor script

Now let’s end this post by looking at the monitoring options for the initiated script. This can be done in real-time, as shown in the step 6, and this can be done by looking at the Script Status node in the Monitoring workspace. Below is on overview of the just triggered script and I’ve included the following highlighted numbers:

  • Number 1 highlights the Show Status button that can be used
    to get the script details, as shown in step 6 of the Run script
    section;
  • Number 2 highlights the Client Task ID that can be used to
    follow the script through the server log files (bgbserver.log) and the client
    log files (ccmnotification.log and script.log), as shown below;
  • Number 3 highlights the Script Guid, as also shown in step
    3 of the Run script section, that can be used to follow the script
    activity in the client log files (script.log), as shown below;
  • Number 4 highlights the Script Output that can be used to
    verify the results. It should refer to the scripted output, as shown in step 3
    of the Create script section.

ConfigMgrConsole_ScriptMonitoring

Let’s continue by following the initiated script through the log files. At least the three log files below are related to this action and together those log files provide a lot of information. As there is some overlap with the log files of last week, I won’t provide the generic information about the log files this time.

BgbServer.log: When initiating a script to run on a client device, this log file shows the information about pushing the script action to the client device, followed by information about the generation of the BGB task status report (.BTS) in the bgb.box inbox (see below). The processing of the BGB task status report can be followed through the bgbmgr.log.

Script_bgbserver

CcmNotificationAgent.log: When initiating a script to run on a client device, this log file shows the arrival of the script action on the client device (see below).

Script_ccmnotification

Script.log: When initiating a script to run on a client device, this log file will show the details about the script that will be executed. That includes the earlier mentioned IDs and the command line that will be used.

Script_script

Let’s end this section by looking at the executed command line in more detail. Below is the highlighted version of the executed command line. That command line clearly shows that the script on the client device is signed, that it uses parameters and that it’s stored locally. The script is stored in C:\Windows\CCM\ScriptStore, which is a hidden folder on the client device. By default only the SYSTEM account has permissions on the script files in that folder.

Executing command line: “C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell.exe” -NoProfile -ExecutionPolicy RemoteSigned -File “C:\Windows\CCM\ScriptStore\D5FF9FBE-D25B-45DB-9771-946076A9FFAD_EB1AA60AF73737F0B342AEED2C5ECB15A9956654BDA4D30263178B3A79E79DD4.ps1” -ServiceName “Group Policy Client”

More information

For more information about the Run Script option, please refer to this article about creating and running PowerShell scripts from the Configuration Manager console.

Combining the powers of the Intune Management Extension and Chocolatey

A bit more than a week ago the Intune Management Extension was added to Microsoft Intune to facilitate the ability to run PowerShell scripts on Windows 10 devices that are managed via MDM. That addition opens a whole new world for managing Windows 10 devices via MDM. Looking at app deployment specifically, this enables the administrator to look at something like Chocolatey for deploying packages. That would make the app deployment via Microsoft Intune suddenly flexible. In this blog post I’ll start with a little introduction about the Intune Management Extension and Chocolatey, followed by the configuration of a PowerShell script to install Chocolatey packages. I’ll end this post by looking at the end result.

Introduction

Let’s start with a short introduction about the awesome Intune Management Extension. The Intune Management Extension supplements the out-of-the-box MDM capabilities of Windows 10. It will be installed automatically on Windows 10 devices, that are managed via MDM, and it simply enables administrators to run PowerShell scripts on Windows 10 devices. Those PowerShell scripts can be used to provide additional capabilities that are missing from the out-of-the-box MDM functionality. The first scenario that the Intune Management Extension enabled, for me, is super easy app deployment via Chocolatey.

Chocolatey is a global PowerShell execution engine using the NuGet packaging infrastructure. Think of it as the ultimate automation tool for Windows. Chocolatey is a package manager that can also embed/wrap native installers and has functions for downloading and check-summing resources from the Internet. Super easy for installing application packages on Windows 10 devices.

Configuration

Now let’s have a look at the configuration. The configuration contains 3 steps. The first step is to create the required PowerShell script, the second step is to upload the PowerShell script to Intune and the third step is to assign the PowerShell script to an Azure AD group.

Step 1: Create PowerShell script

The first step is to create a PowerShell script that will check for the installation of Chocolatey, and that will install Chocolatey if it’s not yet installed. Once Chocolatey is installed the PowerShell script will install the required Chocolatey packages. Now let’s walk through the PowerShell script that I’ll use to do exactly that. The first thing that the script uses, are 2 variables. The first variable $ChocoPackages contains an array with the required Chocolatey packages and the second variable, $ChocoInstall, contains the default installation directory of Chocolatey (see below).

$ChocoPackages = @(“googlechrome”,”adobereader”,”notepadplusplus.install”,”7zip.install”)

$ChocoInstall = Join-Path ([System.Environment]::GetFolderPath(“CommonApplicationData”)) “Chocolatey\bin\choco.exe”

The second thing that the PowerShell script does is verifying the existence of the installation of Chocolatey. This is done by simply testing for the existence of choco.exe by using the $ChocoInstall variable. When choco.exe is not found, the online installation of Chocolatey will be triggered (see below).

if(!(Test-Path $ChocoInstall)) {
     try {

         Invoke-Expression ((New-Object net.webclient).DownloadString(‘https://chocolatey.org/install.ps1’)) -ErrorAction Stop
     }
     catch {
         Throw “Failed to install Chocolatey”
     }      
}

The third and last thing that the PowerShell script does is triggering the installation of the Chocolatey packages. This is done by running through the Chocolatey packages in the $ChocoPackages variable. For every package the installation will be triggered by using Chocolatey (see below).

foreach($Package in $ChocoPackages) {
     try {
         Invoke-Expression “cmd.exe /c $ChocoInstall Install $Package -y” -ErrorAction Stop
     }
     catch {
         Throw “Failed to install $Package”
     }
}

Now put these three pieces together in one script and save it as a PowerShell script (.ps1).

Step 2: Upload PowerShell script

The second step is to upload the created PowerShell script in Intune. To upload the PowerShell script, follow the next 5 steps.

1 Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts;
2 On the Device configuration – PowerShell scripts blade, click Add script to open the Script Settings blade;
3

Intune_AddPowerShellScriptOn the Add PowerShell script blade, provide the following information and click Settings to open the Script Settings blade;

  • Name: Provide a valid name for the PowerShell script policy;
  • Description: (Optional) Provide a description for the PowerShell script policy;
  • Script location: Browse to the PowerShell script.

Note: The script must be less than 10 KB (ASCII) or 5 KB (Unicode).

4

Intune_ScriptSettingsOn the Script Settings blade, provide the following configuration and click OK to return to the PowerShell script blade;

  • Run the script using the logged on credentials: No;
  • Enforce script signature check: No;

Note: Configure Run the script using the logged on credentials to No means that the PowerShell script will run in SYSTEM context;

5 Back on the Add PowerShell script blade, click Create.

Step 3: Assign PowerShell script

The third and last step is to assign the PowerShell script to an Azure AD group. To assign the PowerShell script, follow the next 5 steps.

1 Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts;
2 On the Device configuration – PowerShell scripts blade, select the uploaded PowerShell script and click Assignments to open the {ScriptName} – Assignments blade;
3 On the {ScriptName} – Assignments blade, select the required Azure AD group and click Save.

Note: Keep in mind that the Intune Management Extension synchronizes to Intune once every hour.

Result

Now let’s end this post by looking at the end result. Yes, I can show the installed applications, but it’s better for understanding the process to look at some log files. From an Intune Management Extension perspective, the most interesting log file is IntuneManagementExtension.log. That log file is located at C:\ProgramData\Microsoft\IntuneManagementExtension\Logs. Below is an example, in which I would like to highlight 2 sections:

  1. The first section shows that the first time a PowerShell script arrives on a device, as a policy, the complete script is shown in the log file;
  2. The second section clearly shows the configuration of the PowerShell script, by showing the configuration of the signature check and the context (as configured in step 2.4);

IME_Chocolatey_Result

From a Chocolatey perspective, the most interesting log files are choco.log and choco.summary.log. These log files are located at C:\ProgramData\chocolatey\logs. To show the most interesting information, I would like to highlight 2 sections from the choco.summary.log below:

  1. The first section shows the detection of a Chocolatey packages that is already installed;
  2. The second section shows the installation of a Chocolatey package;

Choco_Chocolatey_Result

The nice thing about Chocolatey is that it already contains a lot of intelligence. A simple example of that is that it checks for the installation of the packages, before starting the installation. That enables me to use one script for installing the packages by simply adding new packages to the $ChocoPackages variable. When the script runs on the client, only the newly added packages will be installed.

Note: Keep in mind that you can also use Chocolatey for updating the installed packages.

More information

For more information about the Intune Management Extension and Chocolatey, please refer to the following articles: