- Remote help for Intune and Microsoft Endpoint Manager - Tue, Jan 25 2022
- Windows 10/11 Azure AD/Intune Enterprise subscription is not valid - Mon, Nov 8 2021
- Upgrade from Windows 10 to Windows 11 with Setupconfig.ini and Intune - Wed, Sep 22 2021
Application approval per email is a great feature, but the thing I'm thinking of is the fact we can right now install and uninstall applications without using collections with or without Active Directory (AD) group queries to populate them, and that's big! I'm someone who always creates two collections per application: one for the install and one for the uninstall. That's a lot of collections, and collection evaluation is expensive from a performance perspective.
How does this work then? You approve an application by using PowerShell, for example, as this serves for automation primarily. You deny the already approved request, which then automatically uninstalls the application. This is really cool, but wait, it takes around 15 seconds in my environment before the installation or uninstallation starts! No more "SMS" (Slow Moving Software) as someone called it back in the SMS days. It is lightning fast.
There is a blog post on TechCommunity by the product group. It contains more information about the source of my sample PowerShell script as well.
To start with, we configure the setting available in the Software Center under Hide Unapproved Applications. This primarily serves for use with an in-house app store, for example, and in this scenario we don't want the users to see all the unapproved apps, which should be all of them if this should work. If we use the Powershell script in the next section to set an additional flag on the deployment of the application, hiding unapproved apps is not needed. The end user will not see them anyway before they are approved.
I have focused my testing around computer-based deployment, and to get this to work, we need to create the application deployment with PowerShell, as the option required is not available in the UI yet. For machine-based preapproved requests to work, you must also enable the Approve application requests for users per device feature.
In this example, I will use 7-Zip 16.04 and 7-Zip 18.06; I have superseded 7-Zip 16.04 with 7-Zip 18.06 to test that as well. To deploy them so I can approve the application for all users on the computers, we run the following PowerShell commands to deploy both versions to all users, require application approval, and make the approval per machine.
New-CMApplicationDeployment -CollectionName "All Systems" -Name "7-Zip 16.04" -DeployAction Install -DeployPurpose Available -ApprovalRequired $true New-CMApplicationDeployment -CollectionName "All Systems" -Name "7-Zip 18.06" -DeployAction Install -DeployPurpose Available -ApprovalRequired $true
We can use three methods in Windows Management Instrumentation (WMI) to approve, deny, and reapprove the application requests and deployments.
To approve the application for the first time, we use the CreateApprovedRequest method, so it both creates the request and approves it using this sample script.
[CmdletBinding()] Param( [string]$MachineName, [string]$AppName, [string]$AutoInstall = $true, [string]$Comments ) Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" $SiteCode = (Get-WmiObject -Namespace root\sms -Query 'SELECT SiteCode FROM SMS_ProviderLocation').SiteCode Set-Location "$($SiteCode):" $NameSpace ="ROOT\SMS\site_$($SiteCode)" $AppID = (Get-CMApplication -Name "$AppName").ModelName $SMSID = (Get-CMDevice -Name "$MachineName").SMSID Invoke-WmiMethod -Path "SMS_ApplicationRequest" -Namespace $NameSpace -Name CreateApprovedRequest -ArgumentList @($AppID, $AutoInstall, $SMSID, $Comments)
We then execute it using the following command line:
Powershell.exe -executionpolicy bypass -file .\CreateApproveApp.ps1 "W10test104" "7-zip 16.04" "TRUE" "Scripted Install"
This then installs the application on the computer; amazing—no collections needed!
And we can see it as approved as well for all users on W10Test04.
If we want to uninstall 7-Zip 16.04 from the test computer, we run the DenyApp.ps1 script:
[CmdletBinding()] Param( [string]$MachineName, [string]$AppName ) Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" $SiteCode = (Get-WmiObject -Namespace root\sms -Query 'SELECT SiteCode FROM SMS_ProviderLocation').SiteCode Set-Location "$($SiteCode):" $NameSpace ="ROOT\SMS\site_$($SiteCode)" $AppID = (Get-CMApplication -Name "$AppName").ModelName $SMSID = (Get-CMDevice -Name "$MachineName").SMSID $reqObj = Get-WmiObject -Namespace $NameSpace -Class SMS_UserApplicationRequest | Where {$_.ModelName -eq $AppID -and $_.RequestedMachine -eq $MachineName} $reqObjPath = $reqObj.__PATH Invoke-WmiMethod -Path $reqObjPath -Name Deny
Execute it using the following parameters:
Powershell.exe -executionpolicy bypass -file .\DenyApp.ps1 "W10test104" "7‑Zip 16.04"
This uninstalls the application.
Application uninstall
And it changes the status under application approval to Denied:
If we want to reapprove it, we need to use the other method. There is already a denied request, so we cannot use the CreateApprovedRequest method; we need to use the Approve method instead.
[CmdletBinding()] Param( [string]$MachineName, [string]$AppName ) Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" $SiteCode = (Get-WmiObject -Namespace root\sms -Query 'SELECT SiteCode FROM SMS_ProviderLocation').SiteCode Set-Location "$($SiteCode):" $NameSpace ="ROOT\SMS\site_$($SiteCode)" $AppID = (Get-CMApplication -Name "$AppName").ModelName $SMSID = (Get-CMDevice -Name "$MachineName").SMSID $reqObj = Get-WmiObject -Namespace $NameSpace -Class SMS_UserApplicationRequest | Where {$_.ModelName -eq $AppID -and $_.RequestedMachine -eq $MachineName} $reqObjPath = $reqObj.__PATH Invoke-WmiMethod -Path $reqObjPath -Name Approve Powershell.exe -executionpolicy bypass -file .\Reapproval.ps1 "W10test104" "7 Zip 16.04"
This reinstalls the application; let's see how fast it really is.
What happens if we deploy 7-Zip 18.06 then, which is configured to supersede 7-Zip 16.04? It handles this as well. Running the ApproveApp.ps1 script with 7-Zip 18.06 will in my example uninstall 7‑Zip 16.04 and install 18.06 automatically—so simple, so fast!
Both versions show up as approved under application approval, but only one version is installed.
What would be a great addition would be a task sequence step to install all approved applications. This would solve application installations during an OS reinstall as well.
Subscribe to 4sysops newsletter!
Test it out in a test environment to start with—the speed will amaze you!
Jörgen,
I appreciate the thorough guide. Two notes I found in making this work in my environment:
Invoke-WmiMethod : Operation is not valid due to the current state of the object.
I am running 1810 at the moment but haven’t applied either of the hotfix patches yet.
Thanks for the tips again!
James Leitz